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
--
Nathan Sidwell
2018-02-16 Nathan Sidwell <nat...@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" }
+ };
+}