diff options
author | Patrick Palka <ppalka@gcc.gnu.org> | 2016-04-26 22:24:43 +0000 |
---|---|---|
committer | Patrick Palka <ppalka@gcc.gnu.org> | 2016-04-26 22:24:43 +0000 |
commit | 843ce8abafc0ba4ff7e15588c9713a784a771f0d (patch) | |
tree | 89e4c1f9086d639dff4c482b7ed34eea53576798 /gcc | |
parent | 3866f82f5847a4bb81a98a18ec7480fefacba74a (diff) | |
download | gcc-843ce8abafc0ba4ff7e15588c9713a784a771f0d.zip gcc-843ce8abafc0ba4ff7e15588c9713a784a771f0d.tar.gz gcc-843ce8abafc0ba4ff7e15588c9713a784a771f0d.tar.bz2 |
Fix PR c++/70241 (inconsistent access with in-class enumeration)
gcc/cp/ChangeLog:
PR c++/70241
* decl.c (build_enumerator): Set current_access_specifier when
declaring an enumerator belonging to an in-class enumeration.
* parser.c (cp_parser_check_access_in_redecleration): Also
consider in-class enumerations.
gcc/testsite/ChangeLog:
PR c++/70241
* g++.dg/cpp0x/enum32.C: New test.
* g++.dg/cpp0x/enum33.C: New test.
From-SVN: r235456
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 28 | ||||
-rw-r--r-- | gcc/cp/parser.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/enum32.C | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/enum33.C | 11 |
6 files changed, 80 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c78abe8..b2185df 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2016-04-26 Patrick Palka <ppalka@gcc.gnu.org> + + PR c++/70241 + * decl.c (build_enumerator): Set current_access_specifier when + declaring an enumerator belonging to an in-class enumeration. + * parser.c (cp_parser_check_access_in_redecleration): Also + consider in-class enumerations. + 2016-04-26 Marek Polacek <polacek@redhat.com> PR c++/70744 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 461822b..a74e9a2 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13686,10 +13686,30 @@ incremented enumerator value is too large for %<long%>"); cplus_decl_attributes (&decl, attributes, 0); if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype)) - /* In something like `struct S { enum E { i = 7 }; };' we put `i' - on the TYPE_FIELDS list for `S'. (That's so that you can say - things like `S::i' later.) */ - finish_member_declaration (decl); + { + /* In something like `struct S { enum E { i = 7 }; };' we put `i' + on the TYPE_FIELDS list for `S'. (That's so that you can say + things like `S::i' later.) */ + + /* The enumerator may be getting declared outside of its enclosing + class, like so: + + class S { public: enum E : int; }; enum S::E : int { i = 7; }; + + For which case we need to make sure that the access of `S::i' + matches the access of `S::E'. */ + tree saved_cas = current_access_specifier; + if (TREE_PRIVATE (TYPE_NAME (enumtype))) + current_access_specifier = access_private_node; + else if (TREE_PROTECTED (TYPE_NAME (enumtype))) + current_access_specifier = access_protected_node; + else + current_access_specifier = access_public_node; + + finish_member_declaration (decl); + + current_access_specifier = saved_cas; + } else pushdecl (decl); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 500a9b3..2dcb766 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -27238,13 +27238,15 @@ cp_parser_check_class_key (enum tag_types class_key, tree type) /* Issue an error message if DECL is redeclared with different access than its original declaration [class.access.spec/3]. - This applies to nested classes and nested class templates. - [class.mem/1]. */ + This applies to nested classes, nested class templates and + enumerations [class.mem/1]. */ static void cp_parser_check_access_in_redeclaration (tree decl, location_t location) { - if (!decl || !CLASS_TYPE_P (TREE_TYPE (decl))) + if (!decl + || (!CLASS_TYPE_P (TREE_TYPE (decl)) + && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE)) return; if ((TREE_PRIVATE (decl) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 12d37f6..8401206 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,4 +1,10 @@ -2016-04-06 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> +2016-04-26 Patrick Palka <ppalka@gcc.gnu.org> + + PR c++/70241 + * g++.dg/cpp0x/enum32.C: New test. + * g++.dg/cpp0x/enum33.C: New test. + +2016-04-26 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> * gcc.c-torture/compile/pr69102.c: Require scheduling support. * gcc.c-torture/compile/pr37669.c: Require >=32 bit integers. diff --git a/gcc/testsuite/g++.dg/cpp0x/enum32.C b/gcc/testsuite/g++.dg/cpp0x/enum32.C new file mode 100644 index 0000000..9d7a7b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum32.C @@ -0,0 +1,25 @@ +// PR c++/70241 +// { dg-do compile { target c++11 } } + +class A { +public: + enum B : int; +}; + +enum A::B : int { + x +}; + +struct C { +private: + enum D : int; +}; + +enum C::D : int { + y +}; + +int main() { + A::x; + C::y; // { dg-error "private" } +} diff --git a/gcc/testsuite/g++.dg/cpp0x/enum33.C b/gcc/testsuite/g++.dg/cpp0x/enum33.C new file mode 100644 index 0000000..ac39741 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum33.C @@ -0,0 +1,11 @@ +// PR c++/70241 +// { dg-do compile { target c++11 } } + +class A { +public: + enum B : int; + enum class C : int; +private: + enum B : int { }; // { dg-error "different access" } + enum class C : int { }; // { dg-error "different access" } +}; |