https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102217
Bug ID: 102217 Summary: co_awaiting a temporary produced by ternary operator crashes (double-free) Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: max at duempel dot org Target Milestone: --- Created attachment 51414 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51414&action=edit Crashing demo program When awaiting a coroutine task which is a temporary evaluated with the ternary operator, GCC emits faulty code that destructs the task twice, leading to a crash due to double free / use-after-free. Tested with "gcc version 10.2.1 20210110 (Debian 10.2.1-6)" and "gcc version 11.2.0 (Debian 11.2.0-1)" clang ("Debian clang version 11.0.1-2") is fine. This crash bug can be worked around by assigning the result of the ternary operator to a local variable first, and then co_await that variable. In my demo program, the UniqueHandle destructor gets called twice with the same contained pointer value; however, the UniqueHandle instance that gets destructed first was never constructed. ASan output with GCC 11: ==2==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000000028 at pc 0x5573042b18a9 bp 0x7ffdde510f60 sp 0x7ffdde510f58 READ of size 8 at 0x606000000028 thread T0 #0 0x5573042b18a8 in Co::UniqueHandle<Co::promise<Foo, Co::Task<Foo> > >::~UniqueHandle() (/home/max/dl/a.out+0x28a8) #1 0x5573042b1284 in FooC(FooC(bool)::_Z4FooCb.frame*) [clone .actor] (/home/max/dl/a.out+0x2284) #2 0x5573042b0582 in FooA(FooA()::_Z4FooAv.frame*) [clone .actor] (/home/max/dl/a.out+0x1582) #3 0x5573042b13a1 in FooC(FooC(bool)::_Z4FooCb.frame*) [clone .actor] (/home/max/dl/a.out+0x23a1) #4 0x5573042b00dd in main (/home/max/dl/a.out+0x10dd) #5 0x7fa1f4ffbe39 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x27e39) #6 0x5573042b01e9 in _start (/home/max/dl/a.out+0x11e9) 0x606000000028 is located 8 bytes inside of 64-byte region [0x606000000020,0x606000000060) freed by thread T0 here: #0 0x7fa1f55b6957 in operator delete(void*) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:160 #1 0x5573042b05b7 in FooA(FooA()::_Z4FooAv.frame*) [clone .actor] (/home/max/dl/a.out+0x15b7) previously allocated by thread T0 here: #0 0x7fa1f55b5f57 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99 #1 0x5573042b0af5 in FooA() (/home/max/dl/a.out+0x1af5)