struct A { int* x[2]; A() { for (int** p=x; p<x+2; ++p) *p = 0; } };
struct B { char c; A a0, a1, a2, a3, *p; B() {} B(const B& b) : c(), a0(b.a0), p(b.p) {} ~B() { delete p; } }; inline void foo(const B& b) { new B(b); } void bar() { foo(B()); foo(B()); } After cfg_cleanup after loop header copying we end up with unfolded &D.2114.a0D.2019.xD.1986[2] > &D.2114.a0D.2019.xD.1986[0] because in fold_binary where we handle this kind of stuff we have if (!offset0 || !offset1 || TREE_TYPE (offset0) == TREE_TYPE (offset1)) { ... and unfortunately the constants 2 and 0 have distinct types: (gdb) call debug_tree(offset0) <integer_cst 0x4026e888 type <integer_type 0x402474ac> constant invariant 8> (gdb) call debug_tree(offset1) <integer_cst 0x4018d180 type <integer_type 0x4019f000 unsigned int> constant invariant 0> -- Summary: Unfolded comparison after cfg_cleanup Product: gcc Version: 4.2.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: middle-end AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: rguenth at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26198