From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8727 invoked by alias); 17 Apr 2016 18:01:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 8708 invoked by uid 89); 17 Apr 2016 18:01:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=sk:cplus_d, type_name, !decl, TYPE_FIELDS X-HELO: mail-qg0-f44.google.com Received: from mail-qg0-f44.google.com (HELO mail-qg0-f44.google.com) (209.85.192.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sun, 17 Apr 2016 18:01:37 +0000 Received: by mail-qg0-f44.google.com with SMTP id v14so15304729qge.0 for ; Sun, 17 Apr 2016 11:01:37 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=9YuJ88f6DUmRuMqLMIdglYlWHU68xKydl3C92/j5dw0=; b=QzilC00NsQ3DGTndz7idISPYAYXKDGdnT8TMDd7qU/eKj9audDxeRc7bpmYWEwfCXC rcHUpf8zhuVgGZjE85OZ3XxBsE/8qBTG4nSDUgHWIBVeKjw8QW29CEjaatls9IJc/VKd 3ptKNDpOJ5RQ7MDP2XBLg/tGKCTuLNvNT5Mn3IXAhYREoZTdbZOAjE3CFFr9/Z8LEQjM RbeAPrFCL5S0M+3aVj1GVrG6hmkVLxFW4zt6w0UExKlfnx4dlu6eFnNfxyPYIQsG44+Z bnwbi5wAngKIdYA3+HuiuvbIr0F1uX5sGArZAD4fpso3b3wiVutWnzdSItFJec2a5Sc9 Qp/g== X-Gm-Message-State: AOPr4FVinIpacyPpjnc9ORlzhUrgJigfog97Ugd/QLldXcUm5C3DLcl+hn/nJkoEitGFqg== X-Received: by 10.140.98.133 with SMTP id o5mr38276439qge.44.1460916095842; Sun, 17 Apr 2016 11:01:35 -0700 (PDT) Received: from localhost.localdomain (ool-4353abbc.dyn.optonline.net. [67.83.171.188]) by smtp.gmail.com with ESMTPSA id n83sm24656090qhn.46.2016.04.17.11.01.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 17 Apr 2016 11:01:35 -0700 (PDT) From: Patrick Palka To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] Fix PR c++/70241 (inconsistent access with in-class enumeration) Date: Sun, 17 Apr 2016 18:01:00 -0000 Message-Id: <1460916090-9444-1-git-send-email-patrick@parcs.ath.cx> X-SW-Source: 2016-04/txt/msg00794.txt.bz2 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 %"); 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