diff mbox series

[PR,c++/81060] ICE with invalid initialzer via lambda

Message ID 0944f774-e972-4e24-8820-fc02c08ce10e@acm.org
State New
Headers show
Series [PR,c++/81060] ICE with invalid initialzer via lambda | expand

Commit Message

Nathan Sidwell Nov. 16, 2017, 12:10 p.m. UTC
This patch fixes a regression my name lookup changes caused earlier this 
year.  We'd already emitted an error about a bogus template definition, 
but the fallout from that now killed us :(

I restored some of the handling r247909 removed.  Namely restoring the 
pushing of a lambda type into the scope enclosing an already-completed 
class.

Interestingly, this caused lambda-template13.C to start complaining 
about a not-defined template needing instantiating on a local (lambda) 
class.  That seems correct to me.  function's ctor is instantiated for 
the default arg in:

   void C::foo (T, function = [] {});

Applying to trunk.

nathan
diff mbox series

Patch

2017-11-16  Nathan Sidwell  <nathan@acm.org>

	PR c++/81060
	* decl.c (xref_tag_1): Push lambda into current scope.
	* name-lookup.c (do_pushtag): Don't deal with ts_lambda here.

	PR c++81060
	* g++.dg/cpp0x/lambda/lambda-template13.C: Avoid undefined
	template using local type error.
	* g++.dg/cpp0x/pr81060.C: New.

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 254786)
+++ cp/decl.c	(working copy)
@@ -13546,8 +13546,12 @@  xref_tag_1 (enum tag_types tag_code, tre
 	  t = make_class_type (code);
 	  TYPE_CONTEXT (t) = context;
 	  if (scope == ts_lambda)
-	    /* Mark it as a lambda type.  */
-	    CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
+	    {
+	      /* Mark it as a lambda type.  */
+	      CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
+	      /* And push it into current scope.  */
+	      scope = ts_current;
+	    }
 	  t = pushtag (name, t, scope);
 	}
     }
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 254786)
+++ cp/name-lookup.c	(working copy)
@@ -6242,9 +6242,7 @@  do_pushtag (tree name, tree type, tag_sc
 	    view of the language.  */
 	 || (b->kind == sk_template_parms
 	     && (b->explicit_spec_p || scope == ts_global))
-	 /* Pushing into a class is ok for lambdas or when we want current  */
 	 || (b->kind == sk_class
-	     && scope != ts_lambda
 	     && (scope != ts_current
 		 /* We may be defining a new type in the initializer
 		    of a static member variable. We allow this when
@@ -6267,7 +6265,6 @@  do_pushtag (tree name, tree type, tag_sc
 	  tree cs = current_scope ();
 
 	  if (scope == ts_current
-	      || scope == ts_lambda
 	      || (cs && TREE_CODE (cs) == FUNCTION_DECL))
 	    context = cs;
 	  else if (cs && TYPE_P (cs))
@@ -6304,8 +6301,7 @@  do_pushtag (tree name, tree type, tag_sc
 
       if (b->kind == sk_class)
 	{
-	  if (!TYPE_BEING_DEFINED (current_class_type)
-	      && scope != ts_lambda)
+	  if (!TYPE_BEING_DEFINED (current_class_type))
 	    return error_mark_node;
 
 	  if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
Index: testsuite/g++.dg/cpp0x/lambda/lambda-template13.C
===================================================================
--- testsuite/g++.dg/cpp0x/lambda/lambda-template13.C	(revision 254786)
+++ testsuite/g++.dg/cpp0x/lambda/lambda-template13.C	(working copy)
@@ -4,7 +4,7 @@ 
 struct function
 {
   template < typename _Functor>
-  function (_Functor);
+  function (_Functor) {}
 };
 
 template <class U>
Index: testsuite/g++.dg/cpp0x/pr81060.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr81060.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr81060.C	(working copy)
@@ -0,0 +1,11 @@ 
+// { dg-do compile  { target c++11 } }
+// PR 81050 ICE in invalid after error
+
+template<typename... T> struct A
+{
+  static const int i;
+};
+
+template<typename... T>
+const int A<T>::i // { dg-error "template definition of non-template" }
+= []{ return 0; }(); // BOOM!