mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 18:16:06 +00:00

We expect that `extern "C"` static functions to be usable in things like inline assembly, as well as ifuncs: See the bug report here: https://github.com/llvm/llvm-project/issues/54549 However, we were diagnosing this as 'not defined', because the ifunc's attempt to look up its resolver would generate a declared IR function. Additionally, as background, the way we allow these static extern "C" functions to work in inline assembly is by making an alias with the C mangling in MOST situations to the version we emit with internal-linkage/mangling. The problem here was multi-fold: First- We generated the alias after the ifunc was checked, so the function by that name didn't exist yet. Second, the ifunc's generation caused a symbol to exist under the name of the alias already (the declared function above), which suppressed the alias generation. This patch fixes all of this by moving the checking of ifuncs/CFE aliases until AFTER we have generated the extern-C alias. Then, it does a 'fixup' around the GlobalIFunc to make sure we correct the reference. Differential Revision: https://reviews.llvm.org/D122608
17 lines
705 B
C++
17 lines
705 B
C++
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-linux-gnu -verify %s
|
|
|
|
extern "C" {
|
|
__attribute__((used)) static void *resolve_foo() { return 0; }
|
|
namespace NS {
|
|
__attribute__((used)) static void *resolve_foo() { return 0; }
|
|
} // namespace NS
|
|
|
|
// FIXME: This diagnostic is pretty confusing, the issue is that the existence
|
|
// of the two functions suppresses the 'alias' creation, and thus the ifunc
|
|
// resolution via the alias as well. In the future we should probably find
|
|
// some way to improve this diagnostic (likely by diagnosing when we decide
|
|
// this case suppresses alias creation).
|
|
__attribute__((ifunc("resolve_foo"))) void foo(); // expected-error{{ifunc must point to a defined function}}
|
|
}
|
|
|