Skip to content

Commit 3b70715

Browse files
authored
[libcxxabi] Use __LDBL_MANT_DIG__ for configuring demangling of long doubles (#134976)
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.
1 parent db27a0a commit 3b70715

File tree

2 files changed

+9
-11
lines changed

2 files changed

+9
-11
lines changed

libcxxabi/src/demangle/ItaniumDemangle.h

+9-7
Original file line numberDiff line numberDiff line change
@@ -5741,14 +5741,16 @@ struct FloatData<double>
57415741
template <>
57425742
struct FloatData<long double>
57435743
{
5744-
#if defined(__mips__) && defined(__mips_n64) || defined(__aarch64__) || \
5745-
defined(__wasm__) || defined(__riscv) || defined(__loongarch__) || \
5746-
defined(__ve__)
5747-
static const size_t mangled_size = 32;
5748-
#elif defined(__arm__) || defined(__mips__) || defined(__hexagon__)
5749-
static const size_t mangled_size = 16;
5744+
#if __LDBL_MANT_DIG__ == 113
5745+
static const size_t mangled_size = 32;
5746+
#elif __LDBL_MANT_DIG__ == 53 || defined(_MSC_VER)
5747+
// MSVC doesn't define __LDBL_MANT_DIG__, but it has long double equal to
5748+
// regular double on all current architectures.
5749+
static const size_t mangled_size = 16;
5750+
#elif __LDBL_MANT_DIG__ == 64
5751+
static const size_t mangled_size = 20;
57505752
#else
5751-
static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
5753+
#error Unknown size for __LDBL_MANT_DIG__
57525754
#endif
57535755
// `-0x1.ffffffffffffffffffffffffffffp+16383` + 'L' + '\0' == 42 bytes.
57545756
// 28 'f's * 4 bits == 112 bits, which is the number of mantissa bits.

libcxxabi/test/test_demangle.pass.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,6 @@
1313
// dd8b266ef.
1414
// UNSUPPORTED: using-built-library-before-llvm-20
1515

16-
// Android's long double on x86[-64] is (64/128)-bits instead of Linux's usual
17-
// 80-bit format, and this demangling test is failing on it.
18-
// XFAIL: LIBCXX-ANDROID-FIXME && target={{i686|x86_64}}-{{.+}}-android{{.*}}
19-
2016
// XFAIL: win32-broken-printf-a-precision
2117

2218
#include "support/timer.h"

0 commit comments

Comments
 (0)