[libcxx-commits] [libcxxabi] [libcxxabi] Use __LDBL_MANT_DIG__ for configuring demangling of long doubles (PR #134976)
Martin Storsjö via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 9 01:52:06 PDT 2025
https://github.com/mstorsjo updated https://github.com/llvm/llvm-project/pull/134976
>From e588b294c8c785190307be07ea963f2647301b02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Wed, 12 Mar 2025 23:46:56 +0200
Subject: [PATCH 1/2] [libcxxabi] Use __LDBL_MANT_DIG__ for configuring
demangling of long doubles
This avoids needing to hardcode the mapping between architectures
and their sizes of long doubles.
This fixes a case in test_demangle.pass.cpp, that previously failed
like this (XFAILed):
.---command stdout------------
| Testing 29859 symbols.
| _ZN5test01hIfEEvRAcvjplstT_Le4001a000000000000000E_c should be invalid but is not
| Got: 0, void test0::h<float>(char (&) [(unsigned int)(sizeof (float) + 0x0.07ff98f7ep-1022L)])
`-----------------------------
.---command stderr------------
| Assertion failed: !passed && "demangle did not fail", file libcxxabi/test/test_demangle.pass.cpp, line 30338
`-----------------------------
This testcase is defined within
// Is long double fp80? (Only x87 extended double has 64-bit mantissa)
#define LDBL_FP80 (__LDBL_MANT_DIG__ == 64)
...
#if !LDBL_FP80
...
#endif
The case failed on x86 architectures with an unusual size for
long doubles, as the test expected the demangler to not be able to
demangle an 80 bit long double (based on the "_LDBL_MANT_DIG__ == 64"
condition in the test). However as the libcxxabi implementation was
hardcoded to demangle 80 bit long doubles on x86_64 regardless of
the actual size, this test failed (by unexpectedly being able to
demangle it).
By configuring libcxxabi's demangling of long doubles to match
what the compiler specifies, we no longer hit the expected failures
in the test_demangle.pass.cpp test on Android on x86.
This makes libcxxabi require a GCC-compatible compiler that defines
nonstandard defines like __LDBL_MANT_DIG__, but I presume that's
already essentially required anyway.
---
libcxxabi/src/demangle/ItaniumDemangle.h | 14 ++++++--------
libcxxabi/test/test_demangle.pass.cpp | 4 ----
2 files changed, 6 insertions(+), 12 deletions(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 4122781beb599..328632d193751 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -5741,14 +5741,12 @@ struct FloatData<double>
template <>
struct FloatData<long double>
{
-#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
- defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \
- defined(__ve__)
- static const size_t mangled_size = 32;
-#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
- static const size_t mangled_size = 16;
-#else
- static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
+#if __LDBL_MANT_DIG__ == 113
+ static const size_t mangled_size = 32;
+#elif __LDBL_MANT_DIG__ == 53
+ static const size_t mangled_size = 16;
+#else // __LDBL_MANT_DIG__ == 64
+ static const size_t mangled_size = 20;
#endif
// `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
// 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index e9c74f70a094b..abaa787f5432b 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -13,10 +13,6 @@
// dd8b266ef.
// UNSUPPORTED: using-built-library-before-llvm-20
-// Android's long double on x86[-64] is (64/128)-bits instead of Linux's usual
-// 80-bit format, and this demangling test is failing on it.
-// XFAIL: LIBCXX-ANDROID-FIXME && target={{i686|x86_64}}-{{.+}}-android{{.*}}
-
// XFAIL: win32-broken-printf-a-precision
#include "support/timer.h"
>From 8821bca642e3fcf50ab802cd025d11f171f7ede6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin at martin.st>
Date: Wed, 9 Apr 2025 11:35:18 +0300
Subject: [PATCH 2/2] Actually check the last case, add an #error if the size
is unhandled
Also check for _MSC_VER for MSVC, as this file is copied and included
in the main LLVM build as well.
---
libcxxabi/src/demangle/ItaniumDemangle.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 328632d193751..b9d17060c04f9 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -5743,10 +5743,14 @@ struct FloatData<long double>
{
#if __LDBL_MANT_DIG__ == 113
static const size_t mangled_size = 32;
-#elif __LDBL_MANT_DIG__ == 53
+#elif __LDBL_MANT_DIG__ == 53 || defined(_MSC_VER)
+ // MSVC doesn't define __LDBL_MANT_DIG__, but it has long double equal to
+ // regular double on all current architectures.
static const size_t mangled_size = 16;
-#else // __LDBL_MANT_DIG__ == 64
+#elif __LDBL_MANT_DIG__ == 64
static const size_t mangled_size = 20;
+#else
+#error Unknown size for __LDBL_MANT_DIG__
#endif
// `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
// 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.
More information about the libcxx-commits
mailing list