On Fri, Apr 25, 2014 at 1:18 PM, Jonathan Wakely <jwakely....@gmail.com> wrote: > On 25 April 2014 11:22, Andrew Haley wrote: >> Summary: Devirtualization uses type information to determine if a >> virtual method is reachable from a call site. If type information >> indicates that it is not, devirt marks the site as unreachable. I >> think this is wrong, and it breaks some programs. At least, it should >> not do this if the user specifies -fno-strict-aliasing. >> >> Consider this class: >> >> class Container { >> void *buffer[5]; >> public: >> EmbeddedObject *obj() { return (EmbeddedObject*)buffer; } >> Container() { new (buffer) EmbeddedObject(); } >> }; >> >> Placement new is used to embed an object in a buffer inside another >> object. Its address can be retrieved. This usage of placement new is >> common, and it even appears as the canonical use of placement new in >> the in the C++ FAQ at >> http://www.parashift.com/c++-faq/placement-new.html. (I am aware that >> this is not strictly legal. For one thing, the memory at buffer may >> not be suitably aligned. Please bear with me.) > > I think the program is strictly legal if you define Container like this: > > class Container { > alignas(EmbeddedObject) char buffer[sizeof(EmbeddedObject)]; > public: > EmbeddedObject *obj() { return (EmbeddedObject*)buffer; } > Container() { new (buffer) EmbeddedObject(); } > }; > > But GCC still does the same transformation and prints nothing, which I > agree is wrong (even with -fstrict-aliasing).
I agree, -fstrict-aliasing has nothing to do with this. Sounds simply like a genuine bug (please open a bugzilla). Thanks, Richard. > With ubsan that program gives: > > sa.cc:9:24: runtime error: load of null pointer of type '<unknown> *' > Segmentation fault (core dumped)