PR c++/84091 - ICE with local class in lambda in template.
authorJason Merrill <jason@redhat.com>
Tue, 30 Jan 2018 20:01:36 +0000 (15:01 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 30 Jan 2018 20:01:36 +0000 (15:01 -0500)
* decl2.c (determine_visibility): Look for outer containing template
instantiation.

From-SVN: r257202

gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-local1.C [new file with mode: 0644]

index 536a3e36107e686e319e27f19777f5ceaf342a6e..ceb1e85632448674f789771241d906d0fa9b5692 100644 (file)
@@ -1,5 +1,9 @@
 2018-01-30  Jason Merrill  <jason@redhat.com>
 
+       PR c++/84091 - ICE with local class in lambda in template.
+       * decl2.c (determine_visibility): Look for outer containing template
+       instantiation.
+
        PR c++/84098 - ICE with lambda in template NSDMI.
        * pt.c (instantiate_class_template_1): Ignore more lambdas.
 
index ef7e6de41c30bf3ed764f9ec53c62837517fd3b8..2da6f9023c5b764947ffc998a85622a4862b1cee 100644 (file)
@@ -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 (file)
index 0000000..a2dd350
--- /dev/null
@@ -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;
+}