------- Comment #73 from rguenth at gcc dot gnu dot org 2007-05-16 15:02 ------- For the following testcase, loop store motion re-orders the writes to *l and *f at -O2. (Note as is, the testcase is only valid for n == 1)
inline void* operator new(unsigned long, void* __p) throw() { return __p; } extern void bar(); long foo(double *p, int n) { long *f; for (int i=0; i<n; ++i) { int *l = (int *)p; *l = 0; f = new (p) long; *f = -1; } bar (); return *f; } and we end up with <bb 2>: if (n > 0) goto <bb 3>; else goto <bb 4>; <bb 3>: f = (long int *) p; <<<change_dynamic_type (long int *) p)>>> # SMT.4_27 = VDEF <SMT.4_19(D)> *f = -1; # SMT.5_35 = VDEF <SMT.5_20(D)> *(int *) p = 0; <bb 4>: # SMT.4_23 = VDEF <SMT.4_32> # SMT.5_24 = VDEF <SMT.5_34> bar (); return *f; which is wrong. Runtime testcase that aborts: inline void* operator new(unsigned long, void* __p) throw() { return __p; } void __attribute__((noinline)) bar() {}; long __attribute__((noinline)) foo(double *p, int n) { long *f; for (int i=0; i<n; ++i) { int *l = (int *)p; *l = 0; f = new (p) long; *f = -1; } bar (); return *f; } extern "C" void abort(void); int main() { union { int i; long l; } u; if (foo((double *)&u, 1) != -1) abort (); return 0; } -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29286