https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106667
Bug ID: 106667
Summary: Diagnosing misuses of capturing lambda coroutines
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: barry.revzin at gmail dot com
Target Milestone: ---
Consider the following example using std::generator from P2502 (sorry the
example isn't super reduced, https://godbolt.org/z/b4vj7E7d1):
int main() {
int lo = 10;
int hi = 20;
auto gen = [=]() -> std::generator<int> {
for (int i = lo; i != hi; ++i) {
co_yield i;
}
}();
for (int i : gen) {
printf("%d\n", i);
}
}
This usage is bad! The lambda captures lo and hi, the coroutine is going to
capture a reference to the lambda, which then gets destroyed. Then we attempt
to access the coroutine, which attempts to read the dead lambda's captures.
ASAN flags the first iteration of that loop as stack-use-after-scope.
Is this situation in general statically diagnosable? The situation here is we
have:
1. A coroutine that is a non-static member function
2. That initially suspends
3. And has non-static data members that are used in the body (or, for lambdas,
captures)
4. And the coroutine outlives the class instance
This will probably be a more common bug in lambdas, specifically, than other
kinds of non-static member functions. This is specifically Core Guideline CP.51
(https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rcoro-capture).