https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94294
Bug ID: 94294 Summary: [missed optimization] new+delete of unused local string not removed Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: eyalroz at technion dot ac.il Target Milestone: --- (Relevant Godbolt: https://godbolt.org/z/GygbjZ) This is the second of two apparent bugs, following bug 94293. They both manifest when compiling the following program: #include <string> int bar() { struct poor_mans_pair { int first; std::string second; }; poor_mans_pair p { 123, "Hey... no small-string optimization for me please!" }; return p.first; } For x86_64, this would ideally compile into: bar(): mov eax, 123 ret but when compiling this with GCC 10.0.1 20200322 (or GCC 9.x etc.), we get assembly which calls operator new[](), populates the string, calls operator delete[](), then returns 123: bar(): sub rsp, 8 mov edi, 51 call operator new(unsigned long) movdqa xmm0, XMMWORD PTR .LC0[rip] mov esi, 51 mov rdi, rax movups XMMWORD PTR [rax], xmm0 movdqa xmm0, XMMWORD PTR .LC1[rip] movups XMMWORD PTR [rax+16], xmm0 movdqa xmm0, XMMWORD PTR .LC2[rip] movups XMMWORD PTR [rax+32], xmm0 mov eax, 8549 mov WORD PTR [rdi+48], ax mov BYTE PTR [rdi+50], 0 call operator delete(void*, unsigned long) mov eax, 123 add rsp, 8 ret .LC0: .quad 7935393319309894984 .quad 3273110194895396975 .LC1: .quad 8007513861377913971 .quad 8386118574366356592 .LC2: .quad 2338053640980164457 .quad 8314037903514690925 This bug report is about how the allocation and de-allocation are not elided/optimized-away, even though the std::string variable is local and unused. AFAICT, g++ is not required to do this. And, in fact, clang++ doesn't do this with its libc++. cppreference says that, starting in C++14, > New-expressions are allowed to elide or combine allocations made > through replaceable allocation functions. In case of elision, the > storage may be provided by the compiler without making the call to > an allocation function (this also permits optimizing out unused > new-expression) and this is, indeed, the case of an unused new-expression. Well, eventually-unused. Note: I suppose it's theoretically possible that this bug only manifests because bug 94293 prevents the allocated space from being recognized as unused; but I can't tell whether that's the case.