Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

Here we have one empty subobject inside another; we didn't create a
CONSTRUCTOR for the outer one, so we don't have it as context for the inner.

        PR c++/125315

gcc/cp/ChangeLog:

        * constexpr.cc (init_subob_ctx): Allow both ctor and object
        to be null for an empty subobject.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp2a/no_unique_address16.C: New test.
---
 gcc/cp/constexpr.cc                              |  7 ++++++-
 gcc/testsuite/g++.dg/cpp2a/no_unique_address16.C | 10 ++++++++++
 2 files changed, 16 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/no_unique_address16.C

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 9916b63d428..1fc8a56503c 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -6718,7 +6718,12 @@ init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx 
&new_ctx,
   else if (ctx->object)
     ctxtype = TREE_TYPE (ctx->object);
   else
-    gcc_unreachable ();
+    {
+      /* This can happen if the enclosing object is also an empty subobject
+        (c++/125315).  */
+      gcc_checking_assert (is_empty_class (type));
+      return;
+    }
 
   if (VECTOR_TYPE_P (type)
       && VECTOR_TYPE_P (ctxtype)
diff --git a/gcc/testsuite/g++.dg/cpp2a/no_unique_address16.C 
b/gcc/testsuite/g++.dg/cpp2a/no_unique_address16.C
new file mode 100644
index 00000000000..22c0b699f92
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/no_unique_address16.C
@@ -0,0 +1,10 @@
+// PR c++/125315
+// { dg-do compile { target c++20 } }
+// { dg-prune-output "used but never defined" }
+
+struct S{~S(){}};
+constexpr S& f(S& t);
+struct W{[[no_unique_address]]S v;};
+struct R:W{};
+S s;
+auto x=R{{f(s)}};

base-commit: 07aa3ec358ae66d512213b2be3c6f9646153bb45
-- 
2.54.0

Reply via email to