Hi,
in this error recovery issue, we provide two correct error messages,
then a bogus one, and then we ICE because much later in
cp_parser_enum_specifier the is_ancestor helper cannot handle
error_mark_node as nested_name_specifier:
51226.C:6:19: error: wrong number of template arguments (0, should be 1)
template<> enum A<>::E : int {}
^
51226.C:1:22: error: provided for ‘template<int <anonymous> > struct A’
template<int> struct A
^
51226.C:6:17: error: ‘E’ is not an enumerator-name
template<> enum A<>::E : int {}
^
51226.C:6: confused by earlier errors, bailing out
With the below, we get only the first two and no ICE. I'm not sure if it
would be more correct to explicitly cp_parser_abort_tentative_parse
before returning: in that case an additional - redundant, in my opinion
- message is emitted:
51226.C:6:24: error: expected unqualified-id before ‘:’ token
template<> enum A<>::E : int {}
Patch tested on x86_64-linux, as usual.
Thanks,
Paolo.
//////////////////////
/cp
2013-05-07 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51226
* parser.c (cp_parser_enum_specifier): Handle nested_name_specifier
== error_mark_node.
/testsuite
2013-05-07 Paolo Carlini <paolo.carl...@oracle.com>
PR c++/51226
* g++.dg/cpp0x/pr51226.C: New.
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 198668)
+++ cp/parser.c (working copy)
@@ -14830,6 +14830,13 @@ cp_parser_enum_specifier (cp_parser* parser)
/*type_p=*/false,
/*is_declaration=*/false);
+ if (nested_name_specifier == error_mark_node)
+ {
+ /* We already issued an error. */
+ pop_deferring_access_checks ();
+ goto out;
+ }
+
if (nested_name_specifier)
{
tree name;
Index: testsuite/g++.dg/cpp0x/pr51226.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr51226.C (revision 0)
+++ testsuite/g++.dg/cpp0x/pr51226.C (working copy)
@@ -0,0 +1,9 @@
+// PR c++/51226
+// { dg-do compile { target c++11 } }
+
+template<int> struct A // { dg-error "provided" }
+{
+ enum E : int;
+};
+
+template<> enum A<>::E : int {} // { dg-error "wrong number" }