Commit 843ce8ab by Patrick Palka

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
parent 3866f82f
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> 2016-04-26 Marek Polacek <polacek@redhat.com>
PR c++/70744 PR c++/70744
......
...@@ -13686,10 +13686,30 @@ incremented enumerator value is too large for %<long%>"); ...@@ -13686,10 +13686,30 @@ incremented enumerator value is too large for %<long%>");
cplus_decl_attributes (&decl, attributes, 0); cplus_decl_attributes (&decl, attributes, 0);
if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype)) 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 /* In something like `struct S { enum E { i = 7 }; };' we put `i'
things like `S::i' later.) */ on the TYPE_FIELDS list for `S'. (That's so that you can say
finish_member_declaration (decl); 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 else
pushdecl (decl); pushdecl (decl);
......
...@@ -27238,13 +27238,15 @@ cp_parser_check_class_key (enum tag_types class_key, tree type) ...@@ -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 /* Issue an error message if DECL is redeclared with different
access than its original declaration [class.access.spec/3]. access than its original declaration [class.access.spec/3].
This applies to nested classes and nested class templates. This applies to nested classes, nested class templates and
[class.mem/1]. */ enumerations [class.mem/1]. */
static void static void
cp_parser_check_access_in_redeclaration (tree decl, location_t location) 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; return;
if ((TREE_PRIVATE (decl) if ((TREE_PRIVATE (decl)
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/pr69102.c: Require scheduling support.
* gcc.c-torture/compile/pr37669.c: Require >=32 bit integers. * gcc.c-torture/compile/pr37669.c: Require >=32 bit integers.
......
// 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" }
}
// 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" }
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment