Nothing in the IL of the following testcase prevents the stores to *q and *r in function doit from being reordered:
extern "C" void * malloc(__SIZE_TYPE__); extern "C" void abort(void); void *p; void __attribute__((noinline)) init(void) { p = malloc(4); } inline void *operator new(__SIZE_TYPE__) { return p; } inline void operator delete (void*) {} int * __attribute__((noinline)) doit(void) { float *q = new float; *q = 1.0; delete q; int *r = new int; *r = 1; return r; } int main() { if (*doit() != 1) abort(); return 0; } from the first alias run results: int* doit() () { void * D.1643; void * D.1643; void * D.1639; void * D.1639; int * r; float * q; <bb 2>: # VUSE <p_14(D)> D.1639_7 = p; q_2 = (float *) D.1639_7; # SMT.6_16 = VDEF <SMT.6_15(D)> *q_2 = 1.0e+0; # VUSE <p_14(D)> D.1643_8 = p; r_4 = (int *) D.1643_8; # SMT.7_18 = VDEF <SMT.7_17(D)> *r_4 = 1; return r_4; } One way to fix this is to make sure that if operator new is inlined we insert a CHANGE_DYNAMIC_TYPE_EXPR. -- Summary: C++ operator new and new expression do not change dynamic type Product: gcc Version: 4.3.0 Status: UNCONFIRMED Keywords: wrong-code, alias Severity: normal Priority: P3 Component: c++ 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=33407