llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.7k stars 11.87k forks source link

[C++20] Itanium name mangling for unevaluated lambda in a local struct does not mangle the function name properly #97024

Open MitalAshok opened 4 months ago

MitalAshok commented 4 months ago

https://godbolt.org/z/E5EbbK3MW

#include <typeinfo>

inline auto f() {
  struct A { using type = decltype([]{}); };
  return A{};
}

inline auto f(int) {
  struct A { using type = decltype([]{}); };
  return A{};
}

using B = decltype(f())::type;
using C = decltype(f(0))::type;

static_assert(!__is_same(B, C));
#if __cpp_lib_constexpr_typeinfo
static_assert(typeid(B) != typeid(C), "not eq at compile time");
#endif

int main() {
  __builtin_printf("%s\n%s\n", typeid(B).name(), typeid(C).name());
  __builtin_printf("eq at runtime? %d\n", typeid(B) == typeid(C));
}

The output produced is:

N1f1AUlvE_E
N1f1AUlvE_E
eq at runtime? 1

When they are clearly different types. For reference, the GCC output is:

Z1fvEN1AUlvE_E
Z1fiEN1AUlvE_E
eq at runtime? 0

Where N1f is replaced with Z1fvE or Z1fiE depending on the function signature (i.e., the function signature is just not taken into account in the mangling).

llvmbot commented 4 months ago

@llvm/issue-subscribers-clang-frontend

Author: Mital Ashok (MitalAshok)

https://godbolt.org/z/E5EbbK3MW ```c++ #include <typeinfo> inline auto f() { struct A { using type = decltype([]{}); }; return A{}; } inline auto f(int) { struct A { using type = decltype([]{}); }; return A{}; } using B = decltype(f())::type; using C = decltype(f(0))::type; static_assert(!__is_same(B, C)); #if __cpp_lib_constexpr_typeinfo static_assert(typeid(B) != typeid(C), "not eq at compile time"); #endif int main() { __builtin_printf("%s\n%s\n", typeid(B).name(), typeid(C).name()); __builtin_printf("eq at runtime? %d\n", typeid(B) == typeid(C)); } ``` The output produced is: ``` N1f1AUlvE_E N1f1AUlvE_E eq at runtime? 1 ``` When they are clearly different types. For reference, the GCC output is: ``` Z1fvEN1AUlvE_E Z1fiEN1AUlvE_E eq at runtime? 0 ``` Where `N1f` is replaced with `Z1fvE` or `Z1fiE` depending on the function signature (i.e., the function signature is just not taken into account in the mangling).