Message ID | c7f63114-d717-d9f7-73d7-cde9cfe2e9e5@oracle.com |
---|---|
State | New |
Headers | show |
Series | [C++,Patch/RFC] PR 84348 ("[7/8 Regression] ICE with invalid friend declaration") | expand |
OK. On Fri, Feb 16, 2018 at 5:30 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote: > 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 } };