diff mbox series

{PR c++/84375] Fix ICE after bad friend

Message ID 9e6c9b16-3541-e6d7-4a7a-d088d12ed60f@acm.org
State New
Headers show
Series {PR c++/84375] Fix ICE after bad friend | expand

Commit Message

Nathan Sidwell Feb. 16, 2018, 2:28 p.m. UTC
This fixes an ICE after attempted friend declaration in a local class. 
We were going onto push it into the local binding, but that's a binding 
in the class being defined, because <history>.  Just bail out immediately.

nathan
diff mbox series

Patch

2018-02-16  Nathan Sidwell  <nathan@acm.org>

	PR c++/84375
	* name-lookup.c (do_pushdecl): Bail out on bad local friend injection.

	* g++.dg/lookup/pr84375.C: New.

Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 257733)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -3079,12 +3079,16 @@  do_pushdecl (tree decl, bool is_friend)
 	  if (is_friend)
 	    {
 	      if (level->kind != sk_namespace)
-		/* In a local class, a friend function declaration must
-		   find a matching decl in the innermost non-class scope.
-		   [class.friend/11] */
-		error ("friend declaration %qD in local class without "
-		       "prior local declaration", decl);
-	      else if (!flag_friend_injection)
+		{
+		  /* In a local class, a friend function declaration must
+		     find a matching decl in the innermost non-class scope.
+		     [class.friend/11] */
+		  error ("friend declaration %qD in local class without "
+			 "prior local declaration", decl);
+		  /* Don't attempt to push it.  */
+		  return error_mark_node;
+		}
+	      if (!flag_friend_injection)
 		/* Hide it from ordinary lookup.  */
 		DECL_ANTICIPATED (decl) = DECL_HIDDEN_FRIEND_P (decl) = true;
 	    }
Index: gcc/testsuite/g++.dg/lookup/pr84375.C
===================================================================
--- gcc/testsuite/g++.dg/lookup/pr84375.C	(revision 0)
+++ gcc/testsuite/g++.dg/lookup/pr84375.C	(working copy)
@@ -0,0 +1,9 @@ 
+// PR c++/84375 ICE after error
+
+void foo()
+{
+  struct A
+  {
+    friend void A(); // { dg-error "local class without prior local" }
+  };
+}