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)