public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-8704] c++: constexpr aggr init of empty class [PR101040]
@ 2021-07-07 21:36 Jason Merrill
  0 siblings, 0 replies; only message in thread
From: Jason Merrill @ 2021-07-07 21:36 UTC (permalink / raw)
  To: gcc-cvs

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{}};


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-07-07 21:36 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-07 21:36 [gcc r11-8704] c++: constexpr aggr init of empty class [PR101040] 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).