From: Jason Merrill Date: Fri, 14 Jul 2023 16:25:51 +0000 (-0400) Subject: c++: constexpr bit_cast with empty field X-Git-Tag: basepoints/gcc-15~7517 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b41a927bcbdf27723b9d420f0b403f2af12129f1;p=thirdparty%2Fgcc.git c++: constexpr bit_cast with empty field The change to only cache constexpr calls that are reduced_constant_expression_p tripped on bit-cast3.C, which failed that predicate due to the presence of an empty field in the result of native_interpret_aggregate, which reduced_constant_expression_p rejects to avoid confusing output_constructor. This patch proposes to skip such fields in native_interpret_aggregate, since they aren't actually involved in the value representation. gcc/ChangeLog: * fold-const.cc (native_interpret_aggregate): Skip empty fields. gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_bit_cast): Check that the result of native_interpret_aggregate doesn't need more evaluation. --- diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 9d85c3be5cc9..6e8f1c2b61ec 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -1440,6 +1440,8 @@ enum value_cat { static tree cxx_eval_constant_expression (const constexpr_ctx *, tree, value_cat, bool *, bool *, tree * = NULL); +static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree, + value_cat, bool *, bool *); static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree, bool * = NULL); static tree find_heap_var_refs (tree *, int *, void *); @@ -4803,6 +4805,13 @@ cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p, { clear_type_padding_in_mask (TREE_TYPE (t), mask); clear_uchar_or_std_byte_in_mask (loc, r, mask); + if (CHECKING_P) + { + tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue, + non_constant_p, overflow_p); + gcc_checking_assert (e == r); + r = e; + } } } diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index a02ede79fed2..7e5494dfd392 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -8935,7 +8935,8 @@ native_interpret_aggregate (tree type, const unsigned char *ptr, int off, return NULL_TREE; for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { - if (TREE_CODE (field) != FIELD_DECL || DECL_PADDING_P (field)) + if (TREE_CODE (field) != FIELD_DECL || DECL_PADDING_P (field) + || is_empty_type (TREE_TYPE (field))) continue; tree fld = field; HOST_WIDE_INT bitoff = 0, pos = 0, sz = 0;