Another refinement to local class handling in determine_visibility. If we're looking at a local class inside a lambda, it thinks it is in a template but the lambda isn't a template instantiation. So look for the enclosing template context to use.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit cc2f223a50dc6477844c7658403fb4be896036e5 Author: Jason Merrill <ja...@redhat.com> Date: Tue Jan 30 07:45:01 2018 -0500 PR c++/84091 - ICE with local class in lambda in template. * decl2.c (determine_visibility): Look for outer containing template instantiation. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index ef7e6de41c3..2da6f9023c5 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -2418,6 +2418,16 @@ determine_visibility (tree decl) by that. */ if (DECL_LANG_SPECIFIC (fn) && DECL_USE_TEMPLATE (fn)) template_decl = fn; + else if (template_decl) + { + /* FN must be a regenerated lambda function, since they don't + have template arguments. Find a containing non-lambda + template instantiation. */ + tree ctx = fn; + while (ctx && !get_template_info (ctx)) + ctx = get_containing_scope (ctx); + template_decl = ctx; + } } else if (VAR_P (decl) && DECL_TINFO_P (decl) && flag_visibility_ms_compat) diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-local1.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-local1.C new file mode 100644 index 00000000000..a2dd350369a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-local1.C @@ -0,0 +1,13 @@ +// PR c++/84091 +// { dg-do compile { target c++11 } } + +template < typename > void f () +{ + [] { struct A {} a; } (); +} + +int main () +{ + f < int > (); + return 0; +}