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). With ubsan that program gives: sa.cc:9:24: runtime error: load of null pointer of type '<unknown> *' Segmentation fault (core dumped)