https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117389
Bug ID: 117389 Summary: std::string that is value-captured by lambda cannot be deconstruct correctly when the lamda is passed as a coroutine argument Product: gcc Version: 12.4.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: sunsijie at buaa dot edu.cn Target Milestone: --- ``` #include <coroutine> #include <functional> #include <string> struct Task { struct promise_type { promise_type() = default; Task get_return_object() { return {std::coroutine_handle<promise_type>::from_promise(*this)}; } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } void unhandled_exception() {} }; std::coroutine_handle<> handle_ = nullptr; }; static inline auto run_lambda(std::function<void()> func) { struct awaitable { [[nodiscard]] auto await_ready() const noexcept -> bool { return true; } auto await_suspend(const std::coroutine_handle<>) noexcept { abort(); } auto await_resume() const noexcept { return; } }; return awaitable{}; } static Task db_put(const std::string& value) { co_await run_lambda([value] { }); } int main() { std::string buf = std::to_string(1); auto t = db_put(buf); t.handle_.resume(); t.handle_.destroy(); return 0; } ``` compile command ``` g++-12 -g -std=gnu++20 -fsanitize=address ./test.cc ``` output ``` ================================================================= ==4082392==ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x50e0000000c0 in thread T0 #0 0x7ffff79d3652 in operator delete(void*, unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:164 #1 0x555555559f8c in std::__new_allocator<char>::deallocate(char*, unsigned long) /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/new_allocator.h:158 #2 0x555555559e5f in std::allocator<char>::deallocate(char*, unsigned long) /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/allocator.h:200 #3 0x555555559e5f in std::allocator_traits<std::allocator<char> >::deallocate(std::allocator<char>&, char*, unsigned long) /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/alloc_traits.h:496 #4 0x555555559a1d in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy(unsigned long) /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/basic_string.h:300 #5 0x555555558f96 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose() /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/basic_string.h:294 #6 0x555555558313 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/basic_string.h:803 #7 0x5555555563bd in ~<lambda> fuck.cc:27 #8 0x555555556ad2 in db_put fuck.cc:28 #9 0x5555555578a7 in std::__n4861::coroutine_handle<void>::resume() const /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/coroutine:135 #10 0x555555556f93 in main fuck.cc:33 #11 0x7ffff7365e07 (/usr/lib/libc.so.6+0x25e07) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3) #12 0x7ffff7365ecb in __libc_start_main (/usr/lib/libc.so.6+0x25ecb) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3) #13 0x555555556284 in _start (/data/project/libraft/tests/a.out+0x2284) (BuildId: 3cbb07674c795006da573cc7196139e3c8cc4b7d) 0x50e0000000c0 is located 128 bytes inside of 152-byte region [0x50e000000040,0x50e0000000d8) allocated by thread T0 here: #0 0x7ffff79d24f2 in operator new(unsigned long) /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_new_delete.cpp:95 #1 0x5555555563ea in db_put fuck.cc:28 #2 0x555555556f81 in main fuck.cc:32 #3 0x7ffff7365e07 (/usr/lib/libc.so.6+0x25e07) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3) #4 0x7ffff7365ecb in __libc_start_main (/usr/lib/libc.so.6+0x25ecb) (BuildId: 98b3d8e0b8c534c769cb871c438b4f8f3a8e4bf3) #5 0x555555556284 in _start (/data/project/libraft/tests/a.out+0x2284) (BuildId: 3cbb07674c795006da573cc7196139e3c8cc4b7d) ```