llvm / llvm/llvm-project

[clang] Incorrect lifetime of lambda `init-capture` temporaries in the `for-range-initializer`

Open
#190,524 1 comment 0 reactions 0 assignees View on GitHub
clang
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

https://godbolt.org/z/83ffqdK5Y

When the `lambda-expression` appears in the `for-range-initializer`, temporaries created in its `init-capture`s do not have their lifetime extended.

```cpp
#include
#include

struct A {
A() { std::cout << "A" << std::endl; }
~A() { std::cout << "~A" << std::endl; }
};

struct B {
B() { std::cout << "B" << std::endl; }
~B() { std::cout << "~B" << std::endl; }
};

struct C {
C() { std::cout << "C" << std::endl; }
~C() { std::cout << "~C" << std::endl; }
};

struct T {
T() {}
T(T const &, A && = {}) {}
};

struct U {
U(B && = {}) {}
};

struct V {
V(C && = {}) {}
};

int main() {
T t;
for (auto _ : [t, u = U{}](V && = {})
{ std::cout << "body" << std::endl;
return std::vector(1, 0); }()) {
std::cout << "iter" << std::endl;
}

return 0;
}
```

x86-64 clang (trunk) --std=c++2c -O2 -pedantic -Wall -Wextra
Output :
```cpp
A
B
C
body
~B
iter
~C
~A
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the example from https://godbolt.org/z/83ffqdK5Y with clang trunk, using the shown C++2c and warning/optimization flags, and compare the destructor order with the reported output. Trace Clang's handling of lambda init-captures in the for-range-initializer; done means the temporary lifetimes are extended as required and the regression is covered by an appropriate compiler test.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.