[Bug libstdc++/29286] [4.0/4.1/4.2/4.3 Regression] placement new does not change the dynamic type as it should

ian at airs dot com gcc-bugzilla@gcc.gnu.org
Fri May 18 17:38:00 GMT 2007



------- 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



More information about the Gcc-bugs mailing list