------- Comment #90 from ian at airs dot com 2007-05-18 18:38 ------- I agree that this is valid:
void f(double *p) { *(int*)p = 3; } void g() { int i; f((double *)&i); } But I don't think that is the question at hand. The variable is always being accessed in the same type, which is also the type of its declaration. The question at hand is this: void f(double* p) { *(int*)p = 3; long *l = new (p) long; *l = 4; } void g() { int i; f((double *)&i); } And the specific question is whether we are permitted to interchange the assignments to *p and *l. Let's consider this: void f(double* p) { *(int*)p = 3; long *l = (long*)p; *l = 4; } Is that valid? Is the compiler permitted to interchange the assignments to *p and *l? Consider that, as in comment #73, p might actually point to a union of int and long. Does that fact that that union might exist somewhere else make this test case valid? Presumably it does not. Presumably this is invalid. So if that is not valid, and the placement new case is valid, then what is the essential difference between the cases? The variable is being accessed via two different types. Why is that OK? You're right that don't have to abandon TBAA to make this work, that we can make it work by turning placement new into a memory barrier. But then you have to address comment #42. That approach will cause a performance regression for natural valid code. The question then becomes whether we are willing to pay that performance regression for normal code in order to support this sort of weird code. Can anybody see a way through this maze? -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29286