Hi,
here we ICE during error recovery when, after emitting a correct error
from grokdeclarator, we go on, we only clear friendp, and grokfield
proceeds to call cp_finish_decl where 'gcc_assert
(CLASS_PLACEHOLDER_TEMPLATE (auto_node));' triggers. We could imagine
solving the problem in various ways... If we want to do something as
early as possible, in grokdeclarator, over the years in turn we handled
different cases in different ways related to the error recovery effects,
mostly. A straightforward solution, which I'm finishing testing, would
be just bailing-out after the error, alternately we could also imagine
something relatively sophisticated like going on, but also setting type
= error_mark_node conditional to type_uses_auto (auto) thus mimicking
the error recovery strategy we use above for a non-friend ill-formed
variant. Just unconditionally setting type = error_mark_node doesn't
seem morally correct to me - even if probably it would also pass the
testsuite - because what we are actually diagnosing to the user, in fact
the first problem in such snippet in parsing order, doesn't have to do
with the type per se, but with friend - the diagnostic for 'friend int
foo' is the same. As usual I'm on x86_64-linux.
Thanks, Paolo.
////////////////////
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 257767)
+++ cp/decl.c (working copy)
@@ -12141,7 +12141,7 @@ grokdeclarator (const cp_declarator *declarator,
{
error ("%qE is neither function nor member function; "
"cannot be declared friend", unqualified_id);
- friendp = 0;
+ return error_mark_node;
}
decl = NULL_TREE;
}
Index: testsuite/g++.dg/cpp0x/auto50.C
===================================================================
--- testsuite/g++.dg/cpp0x/auto50.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/auto50.C (working copy)
@@ -0,0 +1,7 @@
+// PR c++/84348
+// { dg-do compile { target c++11 } }
+
+template<typename> struct A
+{
+ friend auto foo; // { dg-error "cannot be declared friend" }
+};
Index: testsuite/g++.dg/parse/friend12.C
===================================================================
--- testsuite/g++.dg/parse/friend12.C (revision 257767)
+++ testsuite/g++.dg/parse/friend12.C (working copy)
@@ -3,5 +3,4 @@
struct A
{
friend int i = 0; // { dg-error "cannot be declared friend" }
-// { dg-error "non-static data member" "" { target { ! c++11 } } .-1 }
};