Skip to content

[Clang] Missing Cleanup for lambda init-capture temporary in default member initializer #196469

@yuxuanchen1997

Description

@yuxuanchen1997

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions