public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Patrick Palka <ppalka@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r11-8521] c++: using-enum and access specifiers [PR100862]
Date: Mon,  7 Jun 2021 22:37:50 +0000 (GMT)	[thread overview]
Message-ID: <20210607223750.9FEF5388CC02@sourceware.org> (raw)

https://gcc.gnu.org/g:e62029a785b3a5e98123da6ef01ca94c003c306d

commit r11-8521-ge62029a785b3a5e98123da6ef01ca94c003c306d
Author: Patrick Palka <ppalka@redhat.com>
Date:   Thu Jun 3 09:37:11 2021 -0400

    c++: using-enum and access specifiers [PR100862]
    
    When copying the enumerators imported by a class-scope using-enum
    declaration, we need to override current_access_specifier so that
    finish_member_declaration gives the copies the same access as the
    using-enum decl.  (A class-scope using-enum is processed late, so
    current_access_specifier at this point is otherwise set to the last
    access specifier within the class.)  To that end, this patch makes
    handle_using_decl call set_current_access_from_decl accordingly.
    
    For consistency, this patch makes build_enumerator use
    set_current_access_from_decl too.
    
            PR c++/100862
    
    gcc/cp/ChangeLog:
    
            * pt.c (set_current_access_from_decl): Move to ...
            * class.c (set_current_access_from_decl): ... here.
            (handle_using_decl): Use it to propagate the access of the
            using-enum decl to the copy of the imported enumerator.
            * cp-tree.h (set_current_access_from_decl): Declare.
            * decl.c (build_enumerator): Simplify using make_temp_override
            and set_current_access_from_decl.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/using-enum-9.C: New test.
    
    (cherry picked from commit 69f517ac20566a645ff41a9bfca535822205a538)

Diff:
---
 gcc/cp/class.c                            | 15 +++++++++++++++
 gcc/cp/cp-tree.h                          |  1 +
 gcc/cp/decl.c                             | 12 ++----------
 gcc/cp/pt.c                               | 14 --------------
 gcc/testsuite/g++.dg/cpp2a/using-enum-9.C | 28 ++++++++++++++++++++++++++++
 5 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 90b343803a0..25413097ba3 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -207,6 +207,19 @@ static bool type_maybe_constexpr_default_constructor (tree);
 static bool type_maybe_constexpr_destructor (tree);
 static bool field_poverlapping_p (tree);
 
+/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL.  */
+
+void
+set_current_access_from_decl (tree decl)
+{
+  if (TREE_PRIVATE (decl))
+    current_access_specifier = access_private_node;
+  else if (TREE_PROTECTED (decl))
+    current_access_specifier = access_protected_node;
+  else
+    current_access_specifier = access_public_node;
+}
+
 /* Return a COND_EXPR that executes TRUE_STMT if this execution of the
    'structor is in charge of 'structing virtual bases, or FALSE_STMT
    otherwise.  */
@@ -1359,6 +1372,8 @@ handle_using_decl (tree using_decl, tree t)
 	 CONST_DECL_USING_P is true.  */
       gcc_assert (TREE_CODE (decl) == CONST_DECL);
 
+      auto cas = make_temp_override (current_access_specifier);
+      set_current_access_from_decl (using_decl);
       tree copy = copy_decl (decl);
       DECL_CONTEXT (copy) = t;
       DECL_ARTIFICIAL (copy) = true;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 17ba7cbd222..877ed1c1c65 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8161,6 +8161,7 @@ struct atom_hasher : default_hash_traits<tree>
 extern bool subsumes                            (tree, tree);
 
 /* In class.c */
+extern void set_current_access_from_decl (tree);
 extern void cp_finish_injected_record_type (tree);
 
 /* in vtable-class-hierarchy.c */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 32dde5820dc..8908308ec70 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -16286,17 +16286,9 @@ incremented enumerator value is too large for %<long%>"));
 
 	 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;
-
+      auto cas = make_temp_override (current_access_specifier);
+      set_current_access_from_decl (TYPE_NAME (enumtype));
       finish_member_declaration (decl);
-
-      current_access_specifier = saved_cas;
     }
   else
     pushdecl (decl);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 1761a902218..c0e71598d06 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -190,7 +190,6 @@ static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
 static tree tsubst_function_type (tree, tree, tsubst_flags_t, tree);
 static bool check_specialization_scope (void);
 static tree process_partial_specialization (tree);
-static void set_current_access_from_decl (tree);
 static enum template_base_result get_template_base (tree, tree, tree, tree,
 						    bool , tree *);
 static tree try_class_unification (tree, tree, tree, tree, bool);
@@ -26443,19 +26442,6 @@ tsubst_initializer_list (tree t, tree argvec)
   return inits;
 }
 
-/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL.  */
-
-static void
-set_current_access_from_decl (tree decl)
-{
-  if (TREE_PRIVATE (decl))
-    current_access_specifier = access_private_node;
-  else if (TREE_PROTECTED (decl))
-    current_access_specifier = access_protected_node;
-  else
-    current_access_specifier = access_public_node;
-}
-
 /* Instantiate an enumerated type.  TAG is the template type, NEWTAG
    is the instantiation (which should have been created with
    start_enum) and ARGS are the template arguments to use.  */
diff --git a/gcc/testsuite/g++.dg/cpp2a/using-enum-9.C b/gcc/testsuite/g++.dg/cpp2a/using-enum-9.C
new file mode 100644
index 00000000000..3e026057b40
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/using-enum-9.C
@@ -0,0 +1,28 @@
+// PR c++/100862
+// { dg-do compile { target c++20 } }
+
+enum class fruit { orange, apple };
+
+struct A {
+public:
+  using enum fruit;
+private:
+};
+
+struct B {
+protected:
+  using enum fruit;
+public:
+};
+
+struct C {
+private:
+  using enum fruit;
+public:
+};
+
+int main() {
+  A::orange, A::apple;
+  B::orange, B::apple; // { dg-error "protected" }
+  C::orange, C::apple; // { dg-error "private" }
+}


                 reply	other threads:[~2021-06-07 22:37 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210607223750.9FEF5388CC02@sourceware.org \
    --to=ppalka@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).