Files
Kristina Bessonova 7205d7c676 [clang][ItaniumMangle] Fix mangling of lambdas in default member initializers of local classes (#206740)
Lambdas appearing in default member initializers of members of local
classes were previously mangled as if they belonged only to the class
scope, ignoring the enclosing function-local context.

This caused different (but same-named) local classes to produce
identical closure type mangling and corresponding RTTI/IR collisions.

Consider the following example:
```
  void foo() {
    {
      struct T {
        std::function<void()> a = [](){ std::cout << "a"; };
      } t;
      t.a();
    }
    {
      struct T {
        std::function<void()> a = [](){ std::cout << "b"; };
      } t;
      t.a();
    }
  }
```

The expected output is `ab` (and GCC-compiled code behaves accordingly),
while clang previously printed `bb` because the first `T::a` definition
is overridden by the second one due to the missing `<local-name>`
encoding and discriminator required to distinguish the two local `T`
definitions.
2026-07-08 13:36:43 +02:00

34 lines
720 B
C++

// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -O2 -emit-llvm -o /dev/null %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 -O2 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s
struct E {
E();
template<typename T>
E(T t);
~E();
};
E::E() {
struct {
// CHECK-DAG: _ZTSZN1EC1EvEN3$_012anotherValueMUlvE_E
int anotherValue = [x = 1] { return x; }();
} obj;
}
template<typename T>
E::E(T t) {
struct {
// CHECK-DAG: _ZTSZN1EC1IiEET_ENUt_12anotherValueMUlvE_E
int anotherValue = [x = 1] { return x; }();
} obj;
}
E::~E() {
struct {
// CHECK-DAG: _ZTSZN1ED1EvEN3$_012anotherValueMUlvE_E
int anotherValue = [x = 2] { return x; }();
} obj;
}
E e(1);