diff options
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/parser.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/forw_enum12.C | 29 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/forw_enum13.C | 47 |
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" } + }; +}; |