https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80899
Bug ID: 80899 Summary: Devirtualization causes incorrect code generation with placement new in some cases Product: gcc Version: 7.0 Status: UNCONFIRMED Keywords: wrong-code Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: pinskia at gcc dot gnu.org Target Milestone: --- From https://bugs.linaro.org/show_bug.cgi?id=2957: Take: #include <new> struct base { virtual void f() =0; }; template<typename T> struct foo: base { virtual void f() { if (sizeof(T) != sizeof(int)) __builtin_abort(); } }; template<typename T> struct bar { void set() { val = new (&mem) foo<T> (); } void doit() { val->f(); } foo<long long> mem; base *val; }; int main() { bar<int> b; b.set(); b.doit(); return 0; } --- CUT --- This code should not abort as the dynamic type of val is foo<int> due to the placement new in the call in set. But currently aborts at -O2 and above due to the devirtualization deciding the type is statically known as foo<long long>.