[PATCH] D98068: Remove asserts for LocalInstantiationScope

Yaxun Liu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 14 07:07:24 PDT 2021


yaxunl added a comment.

ping

I will provide a detailed description of the issue:

What happen are:

First, fun1 is instantiated as `fun1<0,1>`, which calls lambda function `f(f, Number<1>)`.

This causes lambda function `f` instantiated as `f(f, Number<1>)`. clang uses LocalInstantiationScope to track local variable instantiations, i.e., map var decls in the template to the corresponding var decls in the instantiation. In this case, clang adds two decls to the map: `fs` -> `f`, and `i` -> instantiation of `i` with type `Number<1>`.

This further causes instantiation of lambda function `f` as `f(f, Number<0>)` since `f` contains call of `fs(fs, Number<0>`.  clang adds two decls to its LocalInstantiationScope: `fs` -> `f`, and `i` -> instantiation of `i` with `Number<0>`.

Since `f` is lambda function, clang assumes its instantiation sees the decls in the LocalInstantiationScope of its enclosing template function instantiation, i.e. `f(f,Number<1>)`. However, clang assumes each decl can only show up in LocalInstantiationScope and any enclosing LocalInstantiationScope once, and clang checks and asserts that. In this case, since `f` shows up in LocalInstantiationScope of `f(f, Number<0>)` and `f(f, Number<1>)` twice. This causes assertion.

`LocalInstantiationScope' has a data member `CombineWithOuterScope`, which determines whether a template function instantiation sees the var decls instantiated in its enclosing function template instantiation. For non-lambda functions, this is false, therefor non-lambda functions will not have such issue. For non-recursive lambda function instantiation, such issue will not happen since the var decls will not show up twice.

Functionally, it seems to be OK to have var decls show up twice in `LocalInstantiationScope` for recursive labmda instantiations. For the inner level lambda instantiation, when looking up the var decls, the local var instantiation will be found first. The var instantiation in the outer LocalInstantiationScope will not be found. This is like the inner instantiation hides the outer instantiation. To me, it seems we only need to disable the assertion for the specific case of recursive lambda instantiation.

Any thoughts? Thanks.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98068/new/

https://reviews.llvm.org/D98068



More information about the cfe-commits mailing list