http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60965
Bug ID: 60965 Summary: IPA: Devirtualization versus placement new Product: gcc Version: 4.10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: aph at gcc dot gnu.org Created attachment 32683 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32683&action=edit Reproducer here: 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. 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 may not be strictly legal. For one thing, the memory at buffer may not be suitably aligned. Please bear with me.) The embedded object is an instance of: class EmbeddedObject { public: virtual int val() { return 2; } }; And it is called like this: extern Container o; int main() { cout << o.obj()->val() << endl; } The devirtualization pass looks into the call to val() and the type of o, decides that there is no type inside o that is compatible with EmbeddedObject, and inserts a call to __builtin_unreachanble(). As a result, instead of printing 2, the program does nothing.