On 1/27/25 6:19 PM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/14?
-- >8 --
We've had a wrong-code problem since r14-4140, due to which we
forget to initialize a variable.
In consteval39.C, we evaluate
struct QQQ q;
<<cleanup_point <<< Unknown tree: expr_stmt
QQQ::QQQ (&q, TARGET_EXPR <D.2687, <<< Unknown tree: aggr_init_expr
5
__ct_comp
D.2687
(struct basic_string_view *) <<< Unknown tree: void_cst >>>
(const char *) "" >>>>) >>>>>;
into
struct QQQ q;
<<cleanup_point <<< Unknown tree: expr_stmt
{.data={._M_len=42, ._M_str=0}} >>>>>;
and then the useless expr_stmt is dropped on the floor, so q isn't
initialized. As pre-r14-4140, we need to handle constructors specially.
Hmm, why didn't the following code in eval_outermost make this a
rejects-valid bug rather than wrong-code?
/* If T is calling a constructor to initialize an object, reframe
it as an AGGR_INIT_EXPR to avoid trying to modify an object
from outside the constant evaluation, which will fail even if
the value is actually constant (is_constant_evaluated3.C). */
Your change should share code with this block doing the same thing in
cp_fold_r:
if (TREE_CODE (r) != CALL_EXPR)
{
if (DECL_CONSTRUCTOR_P (callee))
{
loc = EXPR_LOCATION (x);
tree a = CALL_EXPR_ARG (x, 0);
bool return_this = targetm.cxx.cdtor_returns_this ();
if (return_this)
a = cp_save_expr (a);
tree s = build_fold_indirect_ref_loc (loc, a);
r = cp_build_init_expr (s, r);
if (return_this)
r = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (x), r,
fold_convert_loc (loc, TREE_TYPE (x), a));
}
x = r;
break;
}
Like there, we shouldn't need this for AGGR_INIT_EXPR, only CALL_EXPR.
Jason