Hi,

and thanks a lot for your quick and helpful reply.

On 10/21/2015 09:19 PM, Jason Merrill wrote:
On 10/21/2015 04:37 AM, Paolo Carlini wrote:
+            "%qD is not an enumerator-name", identifier);

This should be enum-name or "does not name an enumeration". We should also print the nested-name-specifier.

Agreed

+ error_at (type_start_token->location, "nested name specifier "
+            "for enum declaration cannot depend on a template "
+            "parameter, i.e., %qT", nested_name_specifier);

It can in, e.g.,

template <class T>
enum A<T>::E { ... };

We could hit this same ICE for anything that is not a class or namespace, i.e. any of WILDCARD_TYPE_P. That's the problem here: the nested-name-specifier on a definition needs to name a class or namespace.
In other terms exactly match (in reverse of course) the gcc_assert at the beginning of is_ancestor which triggers in such cases, right?

I'm finishing testing the below, everything is fine so far.

Thanks,
Paolo.

/////////////////////
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 229123)
+++ cp/parser.c (working copy)
@@ -16655,8 +16655,12 @@ cp_parser_enum_specifier (cp_parser* parser)
       else if (nested_name_specifier == error_mark_node)
        /* We already issued an error.  */;
       else
-       error_at (type_start_token->location,
-                 "%qD is not an enumerator-name", identifier);
+       {
+         error_at (type_start_token->location,
+                   "%qD does not name an enumeration in %qT",
+                   identifier, nested_name_specifier);
+         nested_name_specifier = error_mark_node;
+       }
     }
   else
     {
Index: testsuite/g++.dg/parse/enum13.C
===================================================================
--- testsuite/g++.dg/parse/enum13.C     (revision 0)
+++ testsuite/g++.dg/parse/enum13.C     (working copy)
@@ -0,0 +1,8 @@
+// PR c++/66781
+
+class foo
+{
+public:
+  enum foo::bar{};  // { dg-error "does not name an enumeration" }
+  foo::bar baz;
+};
Index: cp/parser.c
===================================================================
--- cp/parser.c (revision 229123)
+++ cp/parser.c (working copy)
@@ -16783,6 +16787,14 @@ cp_parser_enum_specifier (cp_parser* parser)
                        nested_name_specifier);
              type = error_mark_node;
            }
+         else if (TREE_CODE (nested_name_specifier) != NAMESPACE_DECL
+                  && !CLASS_TYPE_P (nested_name_specifier))
+           {
+             error_at (type_start_token->location, "nested name specifier "
+                       "%qT for enum declaration does not name a class "
+                       "or namespace", 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.  */
          else if (prev_scope && !is_ancestor (prev_scope,
Index: testsuite/g++.dg/parse/enum12.C
===================================================================
--- testsuite/g++.dg/parse/enum12.C     (revision 0)
+++ testsuite/g++.dg/parse/enum12.C     (working copy)
@@ -0,0 +1,7 @@
+// PR c++/67847
+
+template < typename T > 
+class D
+{
+  enum T::Color {R, G, B} c; // { dg-error "nested name specifier" }
+};

Reply via email to