c++: lambda in DMI in class template [PR95870]
Here enclosing_instantiation_of was failing to find a match because otctx is struct S<T> and current_function_decl is S<int>::S(), so the latter has more function contexts, and we end up trying to compare S() to NULL_TREE. After spending a bit of time working on establishing the correspondence in this case (class <=> constructor), it occurred to me that we could just use DECL_SOURCE_LOCATION, which is unique for lambdas, since they cannot be redeclared. Since we're so close to release, for now I'm only doing this for the case that was failing before. gcc/cp/ChangeLog: PR c++/95870 * pt.c (enclosing_instantiation_of): Compare DECL_SOURCE_LOCATION if there is no enclosing non-lambda function. gcc/testsuite/ChangeLog: PR c++/95870 * g++.dg/cpp0x/lambda/lambda-nsdmi10.C: New test.
This commit is contained in:
parent
7ebdef2076
commit
62d60246e5
13
gcc/cp/pt.c
13
gcc/cp/pt.c
|
@ -14371,6 +14371,19 @@ enclosing_instantiation_of (tree otctx)
|
|||
|| instantiated_lambda_fn_p (tctx));
|
||||
tctx = decl_function_context (tctx))
|
||||
++lambda_count;
|
||||
|
||||
if (!tctx)
|
||||
{
|
||||
/* Match using DECL_SOURCE_LOCATION, which is unique for all lambdas.
|
||||
|
||||
For GCC 11 the above condition limits this to the previously failing
|
||||
case where all enclosing functions are lambdas (95870). FIXME. */
|
||||
for (tree ofn = fn; ofn; ofn = decl_function_context (ofn))
|
||||
if (DECL_SOURCE_LOCATION (ofn) == DECL_SOURCE_LOCATION (otctx))
|
||||
return ofn;
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
for (; fn; fn = decl_function_context (fn))
|
||||
{
|
||||
tree ofn = fn;
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
// PR c++/95870
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template <typename> struct S {
|
||||
S();
|
||||
int b = []() -> int { enum E {}; return 1; }();
|
||||
};
|
||||
struct C : S<int> {
|
||||
C();
|
||||
};
|
||||
template <typename T> S<T>::S() = default;
|
||||
C::C() {}
|
Loading…
Reference in New Issue