On 5/9/24 12:04, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
-- >8 --
Here we crash on a cp_gimplify_expr/TARGET_EXPR assert:
/* A TARGET_EXPR that expresses direct-initialization should have been
elided by cp_gimplify_init_expr. */
gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
the TARGET_EXPR in question is created for the NSDMI in:
class Vector { int m_size; };
struct S {
const Vector &vec{};
};
where we first need to create a Vector{} temporary, and then bind the
vec reference to it. The temporary is represented by a TARGET_EXPR
and it cannot be elided. When we create an object of type S, we get
D.2848 = {.vec=(const struct Vector &) &TARGET_EXPR <D.2840, {.m_size=0}>}
where the TARGET_EXPR is no longer direct-initializing anything.
Seems like the problem is in convert_like_internal:
bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
if (abstract_virtuals_error (NULL_TREE, totype, complain))
return error_mark_node;
expr = build_value_init (totype, complain);
expr = get_target_expr (expr, complain);
if (expr != error_mark_node)
{
TARGET_EXPR_LIST_INIT_P (expr) = true;
=> TARGET_EXPR_DIRECT_INIT_P (expr) = direct;
}
My patch for 50930 assumed that if a CONSTRUCTOR represents syntactic
direct-initialization, a resulting TARGET_EXPR is itself the direct
initializer, but that isn't the case here; the temporary is
copy-initialized.
We could calculate direct-initializanity from cand->flags, but perhaps
we can just stop trying to set TARGET_EXPR_DIRECT_INIT_P here at all?
We don't do that for other list-initialization in ck_user, I don't know
why I thought it was needed for {} specifically. It doesn't seem to be
needed for the 50930 testcase.
Jason