+2009-06-17 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40389
+ * tree-ssa-operands.c (get_modify_stmt_operands): Add NRV
+ results to the addresses taken bitmap.
+ * tree-scalar-evolution.c (scev_const_prop): Do not insert
+ incomplete stmts into the instruction stream.
+
2009-06-17 Richard Guenther <rguenther@suse.de>
PR middle-end/40460
+2009-06-17 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/40389
+ * g++.dg/torture/pr40389.C: New testcase.
+
2009-06-17 Richard Guenther <rguenther@suse.de>
PR middle-end/40460
--- /dev/null
+/* { dg-do run } */
+
+template <typename V> struct S
+{
+ V *f, *l;
+ __attribute__ ((noinline)) S (void) { f = 0, l = 0; }
+ void foo (V *x)
+ {
+ if (x->p != 0)
+ x->p->n = x->n;
+ else
+ f = x->n;
+ if (x->n != 0)
+ x->n->p = x->p;
+ else
+ l = x->p;
+ }
+ __attribute__ ((noinline)) void bar (V *x)
+ {
+ x->n = 0;
+ x->p = l;
+ if (l != 0)
+ l->n = x;
+ else
+ f = x;
+ l = x;
+ }
+};
+
+struct H;
+
+struct A
+{
+ S <H> k;
+};
+
+struct H
+{
+ A *a;
+ H *p, *n;
+ __attribute__ ((noinline)) H (void) { p = 0, n = 0, a = 0; }
+ __attribute__ ((noinline)) H (A *b) : a (b)
+ {
+ p = 0;
+ n = 0;
+ if (a != 0)
+ a->k.bar (this);
+ }
+ __attribute__ ((noinline)) H (const H &h) : a (h.a)
+ {
+ p = 0;
+ n = 0;
+ if (a != 0)
+ a->k.bar (this);
+ }
+ ~H (void) { if (a != 0) a->k.foo (this); }
+ H &operator= (const H &o)
+ {
+ if (a != 0 || &o == this)
+ __builtin_abort ();
+ a = o.a;
+ if (a != 0)
+ a->k.bar (this);
+ return *this;
+ }
+};
+
+__attribute__ ((noinline))
+H baz (void)
+{
+ return H (new A);
+}
+
+H g;
+
+int
+main (void)
+{
+ g = baz ();
+ if (g.a->k.f != &g)
+ __builtin_abort ();
+ return 0;
+}
+
SSA_NAME_DEF_STMT (rslt) = ass;
{
block_stmt_iterator dest = bsi;
- bsi_insert_before (&dest, ass, BSI_NEW_STMT);
def = force_gimple_operand_bsi (&dest, def, false, NULL_TREE,
true, BSI_SAME_STMT);
+ GIMPLE_STMT_OPERAND (ass, 1) = def;
+ bsi_insert_before (&dest, ass, BSI_NEW_STMT);
}
- GIMPLE_STMT_OPERAND (ass, 1) = def;
update_stmt (ass);
}
}
We used to distinguish between preserving and killing definitions.
We always emit preserving definitions now. */
get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (expr, 0), opf_def);
+
+ /* Make sure the return value is addressable in case of NRV. */
+ if (TREE_CODE (GIMPLE_STMT_OPERAND (expr, 1)) == CALL_EXPR
+ && CALL_EXPR_RETURN_SLOT_OPT (GIMPLE_STMT_OPERAND (expr, 1))
+ && TREE_ADDRESSABLE (TREE_TYPE (GIMPLE_STMT_OPERAND (expr, 0))))
+ {
+ tree t = get_base_address (GIMPLE_STMT_OPERAND (expr, 0));
+ stmt_ann_t s_ann = stmt_ann (stmt);
+ if (t && DECL_P (t) && s_ann)
+ add_to_addressable_set (t, &s_ann->addresses_taken);
+ }
}