summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/parser.c10
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/forw_enum12.C29
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/forw_enum13.C47
5 files changed, 98 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 50f3cc3bfd9..8efaa80b344 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2016-04-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/70513
+ * parser.c (cp_parser_enum_specifier): Check and possibly error for
+ extra qualification.
+
2016-04-20 Nathan Sidwell <nathan@acm.org>
PR c++/55635
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0a1ed1a9710..feb8de76bc3 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -17233,6 +17233,16 @@ 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 (CLASS_TYPE_P (nested_name_specifier)
+ && CLASS_TYPE_P (prev_scope)
+ && same_type_p (nested_name_specifier, prev_scope))
+ {
+ permerror (type_start_token->location,
+ "extra qualification not allowed");
+ nested_name_specifier = NULL_TREE;
+ }
}
if (scoped_enum_p)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c881c000dcf..52257e5bd8a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2016-04-21 Marek Polacek <polacek@redhat.com>
+
+ PR c++/70513
+ * g++.dg/cpp0x/forw_enum12.C: New test.
+ * g++.dg/cpp0x/forw_enum13.C: New test.
+
2016-04-21 Kirill Yukhin <kirill.yukhin@intel.com>
PR target/70728
diff --git a/gcc/testsuite/g++.dg/cpp0x/forw_enum12.C b/gcc/testsuite/g++.dg/cpp0x/forw_enum12.C
new file mode 100644
index 00000000000..906ba68e062
--- /dev/null
+++ b/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" }
+ };
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/forw_enum13.C b/gcc/testsuite/g++.dg/cpp0x/forw_enum13.C
new file mode 100644
index 00000000000..b8027f0c28d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/forw_enum13.C
@@ -0,0 +1,47 @@
+// PR c++/70513
+// { dg-do compile { target c++11 } }
+
+template <typename T>
+class D1
+{
+ enum A : int;
+ enum D1::A : int { foo } c; // { dg-error "extra qualification not allowed" }
+};
+
+template <typename T>
+class D2
+{
+ enum A : int;
+ enum D2<T>::A : int { foo } c; // { dg-error "extra qualification not allowed" }
+};
+
+template <typename T>
+class D3
+{
+ enum D3::A { foo } c; // { dg-error "extra qualification not allowed" }
+};
+
+template <typename T>
+class D4
+{
+ enum D4<T>::A { foo } c; // { dg-error "extra qualification not allowed" }
+};
+
+template <typename T>
+class D5
+{
+ class D6
+ {
+ enum D6::A { foo } c; // { dg-error "extra qualification not allowed" }
+ };
+};
+
+template <typename T>
+class D7
+{
+ class D8
+ {
+ enum A : int;
+ enum D8::A : int { foo } c; // { dg-error "extra qualification not allowed" }
+ };
+};