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)
```