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

Reply via email to