On 12/18/24 1:57 PM, Marek Polacek wrote:
On Tue, Dec 17, 2024 at 11:43:45AM -0500, Jason Merrill wrote:
On 12/12/24 1:42 PM, Marek Polacek wrote:
Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
-- >8 --
This ICE started with the recent prvalue optimization (r15-6052). In
cp_fold_r we have:
if (tree &init = TARGET_EXPR_INITIAL (stmt))
{
cp_walk_tree (&init, cp_fold_r, data, NULL);
// ...
tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt));
What can happen here is that originally the TARGET_EXPR is:
TARGET_EXPR <D.2747, <<< Unknown tree: aggr_init_expr
5
__ct_comp
D.2747
(struct subrange *) <<< Unknown tree: void_cst >>>
&TARGET_EXPR <D.2707, {.it=TARGET_EXPR <D.2695, ...>}> >>>>
but after the first cp_walk_tree we fold the D.2707 TARGET_EXPR into:
TARGET_EXPR <D.2707, <<< Unknown tree: expr_stmt
D.2707.it = TARGET_EXPR <D.2695, ...> >>>>
and then we pass the EXPR_STMT to maybe_constant_init, with D.2707 as
the object. But their types don't match anymore, so we crash. We'd
have to pass D.2707.it as the object for it to work.
But I don't think we need to pass any object to maybe_constant_init;
it'll grab the appropriate one itself.
Hmm, it seems to me that the crash is happening because the deduced type is
wrong, and so with this change we'll end up only producing an initializer
for the first member. Because cp_fold_r throws away the information that
initialized_type needs to know the type of the complete object being
initialized.
Thanks for catching that.
What if we move cp_fold_r of init after the maybe_constant_init?
Sadly, the same crash.
But your idea works, so this is it in a patch form. Thanks again.
Great.
I think with this patch we should be able to remove this now-redundant case:
if (constexpr_dtor)
/* Used for destructors of array elements. */
type = TREE_TYPE (object);
OK with that change.
Jason