/* Like in cxx_eval_store_expression, omit entries for empty fields. */
bool no_slot = new_ctx.ctor == NULL_TREE;
int pos_hint = -1;
- if (new_ctx.ctor != ctx->ctor && !no_slot)
+ if (!ctx->ctor)
+ /* The enclosing object could be an empty subobject so we have no
+ CONSTRUCTOR (c++/125336). */
+ gcc_checking_assert (is_empty_class (type));
+ else if (new_ctx.ctor != ctx->ctor && !no_slot)
{
/* If we built a new CONSTRUCTOR, attach it now so that other
initializers can refer to it. */
/* This is an initializer for an empty field; now that we've
checked that it's constant, we can ignore it. */
changed = true;
- else
+ else if (ctx->ctor)
{
if (TREE_CODE (type) == UNION_TYPE
&& (*p)->last().index != index)
--- /dev/null
+// PR c++/125336
+// { dg-do compile { target c++20 } }
+// { dg-prune-output "used but never defined" }
+
+struct S{ };
+constexpr S& f (S&);
+union W {
+ [[no_unique_address]] S v;
+};
+struct R { W w; };
+S s;
+auto x = R{{ f(s) }};
--- /dev/null
+// PR c++/125336
+// { dg-do compile { target c++20 } }
+// { dg-prune-output "used but never defined" }
+
+struct S { int i; };
+constexpr S& f (S&);
+union W {
+ [[no_unique_address]] S v;
+};
+struct R { W w; };
+S s;
+auto x = R{{ f(s) }};