llvm / llvm-project

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

Mangled names for internal linkage functions in `extern "C"` are different from GCC #88593

Open MaskRay opened 7 months ago

MaskRay commented 7 months ago

This records a name mangling difference with GCC. It's possible that Clang's decision is desired and we should not take any action. (I saw a relevant issue about this but I cannot find it now.)

extern "C" {
static void f0() {}
static void f0(int) {}
}

C++ https://eel.is/c++draft/dcl.link gives an example:

extern "C" {
  static void f4();             // the name of the function f4 has internal linkage,
                                // so f4 has no language linkage; its type has C language linkage
}

If f4 has no language linkage, it seems to make sense to mangle it. So Clang's choice is probably desired.

GCC's decision allows alias/ifunc attributes with an unmangled name like the following:

extern "C" {
static void f0() {}
void g0() __attribute__((alias("f0")));
}

With Clang, _ZL2f0v is needed. This difference makes such alias/ifunc attributes uses in C++ non-portable. However, this probably does not matter because people rarely use alias/ifunc in C++.

I think certain extensions rely on mangling internal linkage functions in extern "C", e.g. __attribute__((overloadable)).

llvmbot commented 7 months ago

@llvm/issue-subscribers-clang-codegen

Author: Fangrui Song (MaskRay)

This records a name mangling difference with GCC. It's possible that Clang's decision is desired and we should not take any action. (I saw a relevant issue about this but I cannot find it now.) ```cpp extern "C" { static void f0() {} static void f0(int) {} } ``` * GCC: error: conflicting declaration of C function ‘void f0(int)’ * Clang: accepted; names are mangled C++ https://eel.is/c++draft/dcl.link gives an example: ``` extern "C" { static void f4(); // the name of the function f4 has internal linkage, // so f4 has no language linkage; its type has C language linkage } ``` If `f4` has no language linkage, it seems to make sense to mangle it. So Clang's choice is probably desired. GCC's decision allows alias/ifunc attributes with an unmangled name: `void g4() __attribute__((alias("f4")))`.
pinskia commented 7 months ago

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 is related. Also https://gcc.gnu.org/legacy-ml/gcc-patches/2007-05/msg00309.html