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

Reply via email to