Skip to content

Commit 92a1d87

Browse files
riogujicama
andcommitted
c++: fix constexpr union with empty member [PR123346]
r14-2820 changed cxx_eval_bare_aggregate to set no_slot based on whether new_ctx.ctor is NULL_TREE, to handle empty subobject elision. However this incorrectly omits entries for empty union members, which later need the entry to exist. This caused valid code to be rejected as non-constant after gcc 13.3, and in trunk caused an ICE when the diagnostic code tries to print a CONSTRUCTOR with a null value. PR c++/123346 gcc/cp/ChangeLog: * constexpr.cc (init_subob_ctx): Do initialize new_ctx.ctor for an empty union member. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-union10.C: New test. Signed-off-by: Egas Ribeiro <egas.g.ribeiro@gmail.com> Co-authored-by: Jason Merrill <jason@redhat.com>
1 parent 13e1fc2 commit 92a1d87

2 files changed

Lines changed: 22 additions & 4 deletions

File tree

gcc/cp/constexpr.cc

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6692,8 +6692,17 @@ init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
66926692
if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
66936693
/* A non-aggregate member doesn't get its own CONSTRUCTOR. */
66946694
return;
6695+
6696+
tree ctxtype = NULL_TREE;
6697+
if (ctx->ctor)
6698+
ctxtype = TREE_TYPE (ctx->ctor);
6699+
else if (ctx->object)
6700+
ctxtype = TREE_TYPE (ctx->object);
6701+
else
6702+
gcc_unreachable ();
6703+
66956704
if (VECTOR_TYPE_P (type)
6696-
&& VECTOR_TYPE_P (TREE_TYPE (ctx->ctor))
6705+
&& VECTOR_TYPE_P (ctxtype)
66976706
&& index == NULL_TREE)
66986707
/* A vector inside of a vector CONSTRUCTOR, e.g. when a larger
66996708
vector is constructed from smaller vectors, doesn't get its own
@@ -6712,9 +6721,10 @@ init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
67126721
new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
67136722
}
67146723

6715-
if (is_empty_class (type))
6716-
/* Leave ctor null for an empty subobject, they aren't represented in the
6717-
result of evaluation. */
6724+
if (is_empty_class (type)
6725+
&& TREE_CODE (ctxtype) != UNION_TYPE)
6726+
/* Leave ctor null for an empty subobject of a non-union class, they aren't
6727+
represented in the result of evaluation. */
67186728
new_ctx.ctor = NULL_TREE;
67196729
else
67206730
{
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// PR c++/123346
2+
// { dg-do compile { target c++20 } }
3+
struct Unit {};
4+
union Union { Unit unit; };
5+
constexpr Union make(Union&& other) {
6+
return Union {.unit = other.unit };
7+
}
8+
constexpr Union u = make(Union { .unit = Unit{} });

0 commit comments

Comments
 (0)