public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jason Merrill <jason@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r11-8704] c++: constexpr aggr init of empty class [PR101040]
Date: Wed,  7 Jul 2021 21:36:03 +0000 (GMT)	[thread overview]
Message-ID: <20210707213603.037943971C11@sourceware.org> (raw)

https://gcc.gnu.org/g:38fed4dfa25ac4894546f0589340ebfc5eef3bee

commit r11-8704-g38fed4dfa25ac4894546f0589340ebfc5eef3bee
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Jun 24 17:32:02 2021 -0400

    c++: constexpr aggr init of empty class [PR101040]
    
    This is basically the aggregate initializer version of PR97566; as in that
    bug, we are trying to initialize empty field 'obj' in 'single' when there's
    no CONSTRUCTOR entry for the 'single' base class subobject of 'derived'.  As
    with that bug, the fix is to stop trying to add entries for empty fields,
    this time in cxx_eval_bare_aggregate.
    
    The change to the other function isn't necessary for this version of
    the patch, but seems worthwhile for robustness anyway.
    
            PR c++/101040
            PR c++/97566
    
    gcc/cp/ChangeLog:
    
            * class.c (is_empty_field): Handle null argument.
            * constexpr.c (cxx_eval_bare_aggregate): Discard initializer
            for empty field.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/no_unique_address13.C: New test.

Diff:
---
 gcc/cp/class.c                                   |  2 +-
 gcc/cp/constexpr.c                               |  9 ++++++++-
 gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C | 24 ++++++++++++++++++++++++
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 25413097ba3..3251aaa1a46 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4249,7 +4249,7 @@ field_poverlapping_p (tree decl)
 bool
 is_empty_field (tree decl)
 {
-  if (TREE_CODE (decl) != FIELD_DECL)
+  if (!decl || TREE_CODE (decl) != FIELD_DECL)
     return false;
 
   bool r = (is_empty_class (TREE_TYPE (decl))
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 0fb0ab44b39..c4bcc561228 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -4438,7 +4438,12 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
   FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
     {
       tree orig_value = value;
-      init_subob_ctx (ctx, new_ctx, index, value);
+      /* Like in cxx_eval_store_expression, omit entries for empty fields.  */
+      bool no_slot = TREE_CODE (type) == RECORD_TYPE && is_empty_field (index);
+      if (no_slot)
+	new_ctx = *ctx;
+      else
+	init_subob_ctx (ctx, new_ctx, index, value);
       int pos_hint = -1;
       if (new_ctx.ctor != ctx->ctor)
 	{
@@ -4484,6 +4489,8 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
 	  gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (index))));
 	  changed = true;
 	}
+      else if (no_slot)
+	changed = true;
       else
 	{
 	  if (TREE_CODE (type) == UNION_TYPE
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C b/gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C
new file mode 100644
index 00000000000..66b83d68137
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address13.C
@@ -0,0 +1,24 @@
+// PR c++/101040
+// { dg-do compile { target c++11 } }
+
+// This class has to be empty.
+struct empty
+{};
+
+// This class has to be empty.
+struct single
+{
+    // This member has to be no_unique_address.
+    [[no_unique_address]] empty obj;
+};
+
+// This class has to be empty and derived from single.
+struct derived : single
+{
+    // This constructor has to be constexpr and take a forwarding reference.
+    template <typename Arg>
+    constexpr derived(Arg&& arg) : single{arg}
+    {}
+};
+
+auto obj = derived{empty{}};


                 reply	other threads:[~2021-07-07 21:36 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=20210707213603.037943971C11@sourceware.org \
    --to=jason@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).