[PATCH] build: Fix multiple test failures with Clang and lld

maozhao 2663432997@qq.com
Fri Sep 26 09:16:50 GMT 2025


When building Glibc with a full LLVM toolchain (Clang 18.1.8, ld.lld), several tests in the `math`, `conform`, and `elf` suites fail. This patch addresses these issues to improve compatibility with Clang/LLVM.

The failures and their fixes are as follows:

1.  **math/test-tgmath* and conform/*tgmath.h* failures:**
    The existing math/Makefile contains logic to disable Glibc's <tgmath.h> when Clang is detected, assuming Clang will use its own built-in version. This leads to test failures. Furthermore, the legacy `fabs` macro definition in Glibc's <tgmath.h> is not fully compatible with Clang's diagnostics.

    This is fixed by:
    - Removing the `no-include` workaround from math/Makefile, forcing the tests to use Glibc's <tgmath.h>.
    - Updating the `fabs` macro in <tgmath.h> to use a C11 `_Generic` implementation for Clang and modern GCC. This provides better diagnostics, avoids `-Wabsolute-value` warnings, and passes the tests.
    - Adding a check in <tgmath.h> to ensure the Glibc header is prioritized during conformance tests.

2.  **elf/ifuncmain* failures with GNU ld:**
    When compiled with Clang, several `ifunc` tests fail during linking with the default GNU ld. Switching the linker to `ld.lld` resolves these `ifunc` related failures. While this is a configuration change, it is a prerequisite for a full Clang-based build and exposes the next issue.

3.  **elf/tst-isa-level-1 failure with ld.lld:**
    Using `ld.lld` introduces a new failure in `elf/tst-isa-level-1`. The test expects `dlopen()` of `tst-isa-level-mod-1-v4.so` to fail on CPUs without x86-64-v4 support. This check relies on the `GNU_PROPERTY_X86_ISA_1_NEEDED` property in the `.note.gnu.property` section of the shared object.

    The root cause is that `ld.lld` discards this note section when it originates from `csu/abi-note.o` during the final link. As a result, the dynamic linker sees no ISA requirement, successfully loads the library, and causes the test to fail because it expected an error.

    This is resolved by modifying `sysdeps/x86/abi-note.c` and `sysdeps/x86/isa-level.c` to emit the property note into a section that `ld.lld` correctly preserves in the final linked object (e.g., `.note.gnu-clang.property`), thus restoring the test's expected behavior.

After these changes, the mentioned test suites pass successfully when building with Clang and linking with lld.

Tested on x86_64 with LLVM/Clang 18.1.8 and `make check`.

        * math/Makefile: Remove `no-include` logic for tgmath tests with
          Clang.
        * math/tgmath.h (fabs): Use C11 `_Generic` implementation for Clang
          and modern GCC.
        (internal macro): Add check to ensure Glibc header is used for
          conformance tests.
        * sysdeps/x86/abi-note.c: Emit ISA property note in a section
          preserved by ld.lld.
        * sysdeps/x86/isa-level.c: Likewise.

Signed-off-by: maozhao <2663432997@qq.com>
---
 math/Makefile           | 12 ++++++------
 math/tgmath.h           | 16 ++++++++++++++++
 sysdeps/x86/abi-note.c  |  2 +-
 sysdeps/x86/isa-level.c |  2 +-
 4 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/math/Makefile b/math/Makefile
index c350914290..8c5bb13a4c 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -1070,13 +1070,13 @@ $(objpfx)test-tgmath3-macro-list.out: gen-tgmath-tests.py
 	$(PYTHON) $< check-list $(tgmath3-macros) > $@; \
 	$(evaluate-test)
 
-ifeq ($(have-test-clang),yes)
+#ifeq ($(have-test-clang),yes)
 # NB: Clang has its own <tgmath.h> and doesn't use <tgmath.h> from glibc.
-define no-include
-$(1).c-no-include-dot = yes
-endef
-$(foreach m,$(tests-tgmath),$(eval $(call no-include,$(m))))
-endif
+#define no-include
+#$(1).c-no-include-dot = yes
+#endef
+#$(foreach m,$(tests-tgmath),$(eval $(call no-include,$(m))))
+#endif
 
 libm-test-fast-math-cflags = -fno-builtin -D__FAST_MATH__ -DTEST_FAST_MATH
 libm-test-vec-cflags = $(libm-test-fast-math-cflags) -fno-inline \
diff --git a/math/tgmath.h b/math/tgmath.h
index cc525e4a2e..337ffa384f 100644
--- a/math/tgmath.h
+++ b/math/tgmath.h
@@ -941,7 +941,23 @@
 #define ceil(Val) __TGMATH_UNARY_REAL_ONLY (Val, ceil)
 
 /* Absolute value of X.  */
+#if __GNUC_PREREQ (4, 9) || defined(__clang__)
+/* Use a C11 _Generic implementation for Clang and modern GCC to provide
+   better diagnostics and avoid false positives from -Wabsolute-value. This
+   is a baseline implementation using only standard C types. */
+#define fabs(x) _Generic((x), \
+    long double: fabsl, \
+    double: fabs, \
+    float: fabsf, \
+    long double _Complex: cabsl, \
+    double _Complex: cabs, \
+    float _Complex: cabsf, \
+    default: fabs \
+  )(x)
+#else
+/* Fallback to the legacy implementation for older compilers. */
 #define fabs(Val) __TGMATH_UNARY_REAL_IMAG_RET_REAL (Val, fabs, cabs)
+#endif
 
 /* Largest integer not greater than X.  */
 #define floor(Val) __TGMATH_UNARY_REAL_ONLY (Val, floor)
diff --git a/sysdeps/x86/abi-note.c b/sysdeps/x86/abi-note.c
index 9525d24df9..107498cacd 100644
--- a/sysdeps/x86/abi-note.c
+++ b/sysdeps/x86/abi-note.c
@@ -25,5 +25,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#include <isa-level.c>
+//#include <isa-level.c>
 #include <csu/abi-note.c>
diff --git a/sysdeps/x86/isa-level.c b/sysdeps/x86/isa-level.c
index be0b9b0c9e..136a8f7378 100644
--- a/sysdeps/x86/isa-level.c
+++ b/sysdeps/x86/isa-level.c
@@ -71,7 +71,7 @@
 #  define note_stringify(arg) note_stringify_1(arg)
 #  define note_stringify_1(arg) #arg
 
-asm(".pushsection \".note.gnu.property\",\"a\",@note\n"
+asm(".pushsection \".note.gnu-clang.property\",\"a\",@note\n"
 "	.p2align " note_stringify (PROPERTY_ALIGN)
 	/* name length.  */
 "\n	.long 1f - 0f\n"
-- 
2.34.1



More information about the Libc-alpha mailing list