This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to fix a part of c++/70513 (ICE-on-invalid with enums)
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jason Merrill <jason at redhat dot com>
- Date: Fri, 8 Apr 2016 13:51:02 +0200
- Subject: C++ PATCH to fix a part of c++/70513 (ICE-on-invalid with enums)
- Authentication-results: sourceware.org; auth=none
This is my attempt to fix at least a part of this PR. I haven't been able to
come up with a fix that fixes the other part involving templates.
We were ICEing on code such as
struct S
{
enum E : int;
enum S::E : int { foo } e;
};
Clang rejects this with "extra qualification" error. When I modified the test
to use structs rather than enums...
struct T
{
struct U;
struct T::U {};
};
...I found out that we reject this with "extra qualification not allowed". So
I think the enum case is missing a similar check that this patch adds.
By the template part of this PR I mean that we ICE on
template <typename T>
class D
{
enum D::A { foo } c;
};
where clang++ says
error: template specialization or definition requires a template parameter list
corresponding to the nested type 'D<T>'
which I guess means that a valid code would have "<T>" after "D". I thought
num_template_headers_for_class and cp_parser_check_template_parameters would
do the job here, but apparently something else needs to be used for this case.
But I'm at my wits' end here.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2016-04-08 Marek Polacek <polacek@redhat.com>
PR c++/70513
* parser.c (cp_parser_enum_specifier): Check for extra qualification.
* g++.dg/cpp0x/forw_enum12.C: New test.
diff --git gcc/cp/parser.c gcc/cp/parser.c
index 28e01af..dc0d1c8 100644
--- gcc/cp/parser.c
+++ gcc/cp/parser.c
@@ -17231,6 +17231,15 @@ cp_parser_enum_specifier (cp_parser* parser)
type, prev_scope, nested_name_specifier);
type = error_mark_node;
}
+ /* If that scope is the scope where the declaration is being placed
+ the program is invalid. */
+ else if (nested_name_specifier == prev_scope)
+ {
+ permerror (type_start_token->location,
+ "extra qualification not allowed");
+ type = error_mark_node;
+ nested_name_specifier = NULL_TREE;
+ }
}
if (scoped_enum_p)
diff --git gcc/testsuite/g++.dg/cpp0x/forw_enum12.C gcc/testsuite/g++.dg/cpp0x/forw_enum12.C
index e69de29..906ba68 100644
--- gcc/testsuite/g++.dg/cpp0x/forw_enum12.C
+++ gcc/testsuite/g++.dg/cpp0x/forw_enum12.C
@@ -0,0 +1,29 @@
+// PR c++/70513
+// { dg-do compile { target c++11 } }
+
+struct S1
+{
+ enum E : int;
+ enum S1::E : int { X } e; // { dg-error "extra qualification not allowed" }
+};
+
+struct S2
+{
+ enum class E : int;
+ enum class S2::E : int { X } e; // { dg-error "extra qualification not allowed" }
+};
+
+struct S3
+{
+ enum struct E : int;
+ enum struct S3::E : int { X } e; // { dg-error "extra qualification not allowed" }
+};
+
+struct S4
+{
+ struct S5
+ {
+ enum E : char;
+ enum S4::S5::E : char { X } e; // { dg-error "extra qualification not allowed" }
+ };
+};
Marek