From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5295 invoked by alias); 22 May 2007 16:20:25 -0000 Received: (qmail 4455 invoked by alias); 22 May 2007 16:19:52 -0000 Date: Tue, 22 May 2007 16:20:00 -0000 Message-ID: <20070522161952.4454.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug libstdc++/29286] [4.0/4.1/4.2/4.3 Regression] placement new does not change the dynamic type as it should In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "mark at codesourcery dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-05/txt/msg01886.txt.bz2 ------- Comment #109 from mark at codesourcery dot com 2007-05-22 17:19 ------- Subject: Re: [4.0/4.1/4.2/4.3 Regression] placement new does not change the dynamic type as it should gdr at cs dot tamu dot edu wrote: > Consider the following instead > > // tu-1.C > void f(int* p) { > *p = 90; > // ... > *(double *) p = 8.3748; > }; > > Is the above code invalid, independent of context? I don't think > you can find a wording in the standard that says it is invalid. IMO, the standard is just not clear with respect to aliasing. We cannot rely upon it, except as a guide. As I've said throughout this thread, it doesn't make sense to try to do "close reading" of the standard for aliasing issues because it just wasn't written with those issues in mind, just as there are all of the famous memory model issues in C. In any case, I consider the code above invalid. > Indeed, consider this: > > // tu-2.C > void f(int*); > void g() { > union { > int i; > double d; > } t; > > t.i = 42; > f(&t); > cout << t.d << endl; > } > > I believe we can all agree the definition of g is valid. No, I do not. And GCC historically has not; you are only allowed to use the union for type-punning if the accesses are through the union directly. That was the decision we made a long time ago regarding TBAA, and it even appears in the manual; the -fstrict-aliasing documentation says: "The practice of reading from a different union member than the one most recently written to (called ``type-punning'') is common. Even with @option{-fstrict-aliasing}, type-punning is allowed, provided the memory is accessed through the union type. So, the code above will work as expected. However, this code might not: @smallexample int f() @{ a_union t; int* ip; t.d = 3.0; ip = &t.i; return *ip; @} @end smallexample" The point here is that the compiler is allowed to decide that t.d does not alias "*ip" because the latter is not a direct access through the union. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29286