diff mbox series

C++ PATCH for c++/84091, ICE with local class in lambda in template

Message ID CADzB+2=-7mGM68auSC8vxWHa5bc1ujFCDtp0vetVhqzaOny+Zw@mail.gmail.com
State New
Headers show
Series C++ PATCH for c++/84091, ICE with local class in lambda in template | expand

Commit Message

Jason Merrill Jan. 30, 2018, 7:59 p.m. UTC
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 <jason@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 mbox series

Patch

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;
+}