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

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to