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

Reply via email to