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)

Reply via email to