Message ID | 52E02B4A.8090001@oracle.com |
---|---|
State | New |
Headers | show |
Yep, that's along the lines I was thinking of. But again, prev_scope is irrelevant here, so the new code shouldn't mention it at all. -------- Original Message -------- From: Paolo Carlini <paolo.carlini@oracle.com> Sent: Wed, Jan 22, 2014 03:34 PM To: Jason Merrill <jason@redhat.com>; gcc-patches@gcc.gnu.org CC: Subject: Re: [C++ Patch] PR 58980 Hi, On 01/22/2014 06:13 PM, Jason Merrill wrote: > On 01/21/2014 09:55 AM, Jason Merrill wrote: >> I think I would prefer to change the "child" assert to be >> MAYBE_CLASS_TYPE_P rather than CLASS_TYPE_P. > On second thought, no, I think we do want to specifically handle > TYPENAME_TYPE. But I think we want a different error message; getting > a TYPENAME_TYPE here means that B has not been declared. The current > scope is irrelevant. So we want to check for TYPENAME_TYPE before we > think about checking prev_scope. Ok. In fact I entertained myself this kind of reasoning, a couple of days ago... I tested the below, which uses "by hand" %Es instead of %qT for more concise error messages (consistent with the non-template case). Thanks, Paolo. ////////////////////
Index: cp/parser.c =================================================================== --- cp/parser.c (revision 206933) +++ cp/parser.c (working copy) @@ -15469,9 +15469,17 @@ cp_parser_enum_specifier (cp_parser* parser) error_at (type_start_token->location, "cannot add an enumerator " "list to a template instantiation"); + if (prev_scope && TREE_CODE (nested_name_specifier) == TYPENAME_TYPE) + { + error_at (type_start_token->location, + "%<%E::%E%> has not been declared", + prev_scope, nested_name_specifier); + type = error_mark_node; + } /* If that scope does not contain the scope in which the class was originally declared, the program is invalid. */ - if (prev_scope && !is_ancestor (prev_scope, nested_name_specifier)) + else if (prev_scope && !is_ancestor (prev_scope, + nested_name_specifier)) { if (at_namespace_scope_p ()) error_at (type_start_token->location, @@ -15480,7 +15488,8 @@ cp_parser_enum_specifier (cp_parser* parser) type, prev_scope, nested_name_specifier); else error_at (type_start_token->location, - "declaration of %qD in %qD which does not enclose %qD", + "declaration of %qD in %qD which does not " + "enclose %qD", type, prev_scope, nested_name_specifier); type = error_mark_node; } Index: testsuite/g++.dg/parse/enum11.C =================================================================== --- testsuite/g++.dg/parse/enum11.C (revision 0) +++ testsuite/g++.dg/parse/enum11.C (working copy) @@ -0,0 +1,6 @@ +// PR c++/58980 + +template<typename> struct A +{ + enum A::B::C {}; // { dg-error "has not been declared" } +};