Clang 20+ fails to emit clean up to a temporary lambda closure object when the lambda appears in a default member initializer that is used during aggregate initialization.
This appears to be a regression introduced by 0601370.
Repro:
#include <cstdio>
namespace {
class Function {
public:
template <typename F>
explicit Function(F f) : callable_{new Callable<F>{static_cast<F&&>(f)}} {
std::fprintf(stderr, "Function constructed at %p\n", this);
}
~Function() {
std::fprintf(stderr, "Function destroyed at %p\n", this);
delete callable_;
}
private:
struct CallableBase {
virtual ~CallableBase() = default;
};
template <typename F>
struct Callable final : CallableBase {
explicit Callable(F f) : function{static_cast<F&&>(f)} {}
F function;
};
CallableBase* callable_;
};
struct Noisy {
Noisy() : value{new int{1}} {
std::fprintf(stderr, "Noisy constructed at %p with %p\n", this, value);
}
Noisy(const Noisy& other) : value{new int{*other.value}} {
std::fprintf(stderr, "Noisy copy-constructed at %p with %p\n", this, value);
}
~Noisy() {
std::fprintf(stderr, "Noisy destroyed at %p with %p\n", this, value);
delete value;
}
int* value;
};
struct Options {
Function function{[noisy = Noisy{}] {}};
};
Options kOptions{};
} // namespace
int main() {
return 0;
}
Godbolt: https://godbolt.org/z/nq796szPW
Clang 19 corrected emitted 3 destructor calls to Noisy in this program while Clang 20+ emits only 2.
Clang 20+ fails to emit clean up to a temporary lambda closure object when the lambda appears in a default member initializer that is used during aggregate initialization.
This appears to be a regression introduced by 0601370.
Repro:
Godbolt: https://godbolt.org/z/nq796szPW
Clang 19 corrected emitted 3 destructor calls to Noisy in this program while Clang 20+ emits only 2.