if (init)
{
- tree cleanup = NULL_TREE;
+ gimple_seq init_pre_p = NULL;
/* TARGET_EXPR temps aren't part of the enclosing block, so add it
to the temps list. Handle also variable length TARGET_EXPRs. */
if (!poly_int_tree_p (DECL_SIZE (temp)))
{
if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
- gimplify_type_sizes (TREE_TYPE (temp), pre_p);
+ gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
/* FIXME: this is correct only when the size of the type does
not depend on expressions evaluated in init. */
- gimplify_vla_decl (temp, pre_p);
+ gimplify_vla_decl (temp, &init_pre_p);
}
else
{
/* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
expression is supposed to initialize the slot. */
if (VOID_TYPE_P (TREE_TYPE (init)))
- ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+ ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
+ fb_none);
else
{
tree init_expr = build2 (INIT_EXPR, void_type_node, temp, init);
init = init_expr;
- ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+ ret = gimplify_expr (&init, &init_pre_p, post_p, is_gimple_stmt,
+ fb_none);
init = NULL;
ggc_free (init_expr);
}
TARGET_EXPR_INITIAL (targ) = NULL_TREE;
return GS_ERROR;
}
- if (init)
- gimplify_and_add (init, pre_p);
- /* If needed, push the cleanup for the temp. */
- if (TARGET_EXPR_CLEANUP (targ))
- {
- if (CLEANUP_EH_ONLY (targ))
- gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
- CLEANUP_EH_ONLY (targ), pre_p);
- else
- cleanup = TARGET_EXPR_CLEANUP (targ);
- }
+ if (init)
+ gimplify_and_add (init, &init_pre_p);
/* Add a clobber for the temporary going out of scope, like
gimplify_bind_expr. */
}
}
}
- if (cleanup)
- gimple_push_cleanup (temp, cleanup, false, pre_p);
+
+ gimple_seq_add_seq (pre_p, init_pre_p);
+
+ /* If needed, push the cleanup for the temp. */
+ if (TARGET_EXPR_CLEANUP (targ))
+ gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
+ CLEANUP_EH_ONLY (targ), pre_p);
/* Only expand this once. */
TREE_OPERAND (targ, 3) = init;
--- /dev/null
+// PR middle-end/103984
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -Wuninitialized" }
+
+struct A {
+ char *a;
+ char b[4];
+ A ();
+ A (const A &);
+ A (const char *);
+ A (const char *, const char *);
+ [[gnu::always_inline]] ~A () { if (a != b) delete a; }
+};
+struct B {
+ const char *c = nullptr;
+ const char *d = nullptr;
+ A qux () const { return A (c, d); }
+ B (const char *x) : c(x), d(x) { d += __builtin_strlen (x); }
+ B (const B &x) { c = x.c; d = x.d; }
+};
+struct C { A e; int f; };
+extern int baz (B);
+void bar (C &&);
+
+void
+foo (char **x)
+{
+ const A g ("foo");
+ const B h = x[0];
+ bar (C { h.qux (), baz (h) });
+}