* [PATCH] Fix PR c++/70241 (inconsistent access with in-class enumeration)
@ 2016-04-17 18:01 Patrick Palka
2016-04-25 17:41 ` Patrick Palka
2016-04-25 19:24 ` Jason Merrill
0 siblings, 2 replies; 3+ messages in thread
From: Patrick Palka @ 2016-04-17 18:01 UTC (permalink / raw)
To: gcc-patches; +Cc: jason, Patrick Palka
When an in-class unscoped enumeration is defined out-of-line its
enumerators currently don't inherit the access of the enumeration. This
patch makes the access of the enumerations defined out-of-line match the
access of the enumerator.
Also, we currently don't check that redeclarations of in-class
enumerations have the same access, which this patch fixes as well.
Bootstrapped + regtested on x86_64-pc-linux-gnu, does this look OK to
commit?
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.
---
gcc/cp/decl.c | 28 ++++++++++++++++++++++++----
gcc/cp/parser.c | 8 +++++---
gcc/testsuite/g++.dg/cpp0x/enum32.C | 25 +++++++++++++++++++++++++
gcc/testsuite/g++.dg/cpp0x/enum33.C | 11 +++++++++++
4 files changed, 65 insertions(+), 7 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum32.C
create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum33.C
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index f9f12a7..0f217a5 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13694,10 +13694,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 5486129..f782d70 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -27228,13 +27228,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/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" }
+};
--
2.8.1.231.g95ac767
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Fix PR c++/70241 (inconsistent access with in-class enumeration)
2016-04-17 18:01 [PATCH] Fix PR c++/70241 (inconsistent access with in-class enumeration) Patrick Palka
@ 2016-04-25 17:41 ` Patrick Palka
2016-04-25 19:24 ` Jason Merrill
1 sibling, 0 replies; 3+ messages in thread
From: Patrick Palka @ 2016-04-25 17:41 UTC (permalink / raw)
To: GCC Patches; +Cc: Jason Merrill, Patrick Palka
On Sun, Apr 17, 2016 at 2:01 PM, Patrick Palka <patrick@parcs.ath.cx> wrote:
> When an in-class unscoped enumeration is defined out-of-line its
> enumerators currently don't inherit the access of the enumeration. This
> patch makes the access of the enumerations defined out-of-line match the
> access of the enumerator.
>
> Also, we currently don't check that redeclarations of in-class
> enumerations have the same access, which this patch fixes as well.
>
> Bootstrapped + regtested on x86_64-pc-linux-gnu, does this look OK to
> commit?
>
> 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.
> ---
> gcc/cp/decl.c | 28 ++++++++++++++++++++++++----
> gcc/cp/parser.c | 8 +++++---
> gcc/testsuite/g++.dg/cpp0x/enum32.C | 25 +++++++++++++++++++++++++
> gcc/testsuite/g++.dg/cpp0x/enum33.C | 11 +++++++++++
> 4 files changed, 65 insertions(+), 7 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum32.C
> create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum33.C
>
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index f9f12a7..0f217a5 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -13694,10 +13694,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 5486129..f782d70 100644
> --- a/gcc/cp/parser.c
> +++ b/gcc/cp/parser.c
> @@ -27228,13 +27228,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/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" }
> +};
> --
> 2.8.1.231.g95ac767
>
Ping.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] Fix PR c++/70241 (inconsistent access with in-class enumeration)
2016-04-17 18:01 [PATCH] Fix PR c++/70241 (inconsistent access with in-class enumeration) Patrick Palka
2016-04-25 17:41 ` Patrick Palka
@ 2016-04-25 19:24 ` Jason Merrill
1 sibling, 0 replies; 3+ messages in thread
From: Jason Merrill @ 2016-04-25 19:24 UTC (permalink / raw)
To: Patrick Palka, gcc-patches
OK.
Jason
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-04-25 19:24 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-17 18:01 [PATCH] Fix PR c++/70241 (inconsistent access with in-class enumeration) Patrick Palka
2016-04-25 17:41 ` Patrick Palka
2016-04-25 19:24 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).