[libcxx-commits] [libcxxabi] [llvm] [ItaniumDemangle] Set `InConstraintExpr` to `true` when demangling a constraint expression (PR #107385)

Viktoriia Bakalova via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 11 09:04:55 PDT 2024


https://github.com/VitaNuo updated https://github.com/llvm/llvm-project/pull/107385

>From cfc467d4c04f79b331a0febf0e840b254dbdfbb6 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Tue, 10 Sep 2024 09:40:03 +0000
Subject: [PATCH 1/3] [ItaniumDemangle] Set InConstraintExpr to true when
 demangling a constraint expression. This prevents demangler failures until
 the TODO in the
 [demangler](https://github.com/llvm/llvm-project/blob/3e070906eff720dc44aee86e533e12aafc8bb14b/llvm/include/llvm/Demangle/ItaniumDemangle.h#L5678)
 is implemented. This is a temporary fix for
 [#89914](https://github.com/llvm/llvm-project/issues/89914).

---
 libcxxabi/src/demangle/ItaniumDemangle.h            | 13 ++++++++++---
 llvm/include/llvm/Demangle/ItaniumDemangle.h        | 13 ++++++++++---
 .../llvm-cxxfilt/demangle-constrained-template.test |  3 +++
 3 files changed, 23 insertions(+), 6 deletions(-)
 create mode 100644 llvm/test/tools/llvm-cxxfilt/demangle-constrained-template.test

diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 88de234a6e0b92..3b041efe3aac00 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -2677,7 +2677,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
 
   bool TryToParseTemplateArgs = true;
   bool PermitForwardTemplateReferences = false;
-  bool InConstraintExpr = false;
+  bool HasIncompleteTemplateParameterTracking = false;
   size_t ParsingLambdaParamsAtLevel = (size_t)-1;
 
   unsigned NumSyntheticTemplateParameters[3] = {};
@@ -4818,7 +4818,8 @@ template <typename Derived, typename Alloc>
 Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
   // Within this expression, all enclosing template parameter lists are in
   // scope.
-  ScopedOverride<bool> SaveInConstraintExpr(InConstraintExpr, true);
+  ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
+      HasIncompleteTemplateParameterTracking, true);
   return getDerived().parseExpr();
 }
 
@@ -5676,7 +5677,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
   // substitute them all within a <constraint-expression>, so print the
   // parameter numbering instead for now.
   // TODO: Track all enclosing template parameters and substitute them here.
-  if (InConstraintExpr) {
+  if (HasIncompleteTemplateParameterTracking) {
     return make<NameType>(std::string_view(Begin, First - 1 - Begin));
   }
 
@@ -5737,6 +5738,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
   }
 
   if (consumeIf("Tk")) {
+    // We don't track enclosing template parameter levels well enough to
+    // reliably demangle template parameter substitutions, so print an arbitrary
+    // string in place of a parameter for now.
+    // TODO: Track all enclosing template parameters and demangle substitutions.
+    ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
+        HasIncompleteTemplateParameterTracking, true);
     Node *Constraint = getDerived().parseName();
     if (!Constraint)
       return nullptr;
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index fb2060fa07f724..0af0224bc83fa8 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -2677,7 +2677,7 @@ template <typename Derived, typename Alloc> struct AbstractManglingParser {
 
   bool TryToParseTemplateArgs = true;
   bool PermitForwardTemplateReferences = false;
-  bool InConstraintExpr = false;
+  bool HasIncompleteTemplateParameterTracking = false;
   size_t ParsingLambdaParamsAtLevel = (size_t)-1;
 
   unsigned NumSyntheticTemplateParameters[3] = {};
@@ -4818,7 +4818,8 @@ template <typename Derived, typename Alloc>
 Node *AbstractManglingParser<Derived, Alloc>::parseConstraintExpr() {
   // Within this expression, all enclosing template parameter lists are in
   // scope.
-  ScopedOverride<bool> SaveInConstraintExpr(InConstraintExpr, true);
+  ScopedOverride<bool> SaveIncompleteTemplateParameterTracking(
+      HasIncompleteTemplateParameterTracking, true);
   return getDerived().parseExpr();
 }
 
@@ -5676,7 +5677,7 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParam() {
   // substitute them all within a <constraint-expression>, so print the
   // parameter numbering instead for now.
   // TODO: Track all enclosing template parameters and substitute them here.
-  if (InConstraintExpr) {
+  if (HasIncompleteTemplateParameterTracking) {
     return make<NameType>(std::string_view(Begin, First - 1 - Begin));
   }
 
@@ -5737,6 +5738,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseTemplateParamDecl(
   }
 
   if (consumeIf("Tk")) {
+    // We don't track enclosing template parameter levels well enough to
+    // reliably demangle template parameter substitutions, so print an arbitrary
+    // string in place of a parameter for now.
+    // TODO: Track all enclosing template parameters and demangle substitutions.
+    ScopedOverride<bool> SaveIncompleteTemplateParameterTrackingExpr(
+        HasIncompleteTemplateParameterTracking, true);
     Node *Constraint = getDerived().parseName();
     if (!Constraint)
       return nullptr;
diff --git a/llvm/test/tools/llvm-cxxfilt/demangle-constrained-template.test b/llvm/test/tools/llvm-cxxfilt/demangle-constrained-template.test
new file mode 100644
index 00000000000000..7a038ebb77a06d
--- /dev/null
+++ b/llvm/test/tools/llvm-cxxfilt/demangle-constrained-template.test
@@ -0,0 +1,3 @@
+RUN: llvm-cxxfilt -n _ZN3FooIiE6methodITk4TrueIT_EiEEvS3_ | FileCheck %s
+
+CHECK: void Foo<int>::method<int>(T)
\ No newline at end of file

>From cc3bd6affb58d78ef703f47a749dcdb83715beb4 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Tue, 10 Sep 2024 09:40:03 +0000
Subject: [PATCH 2/3] [ItaniumDemangle] Set InConstraintExpr to true when
 demangling a constraint expression. This prevents demangler failures until
 the TODO in the
 [demangler](https://github.com/llvm/llvm-project/blob/3e070906eff720dc44aee86e533e12aafc8bb14b/llvm/include/llvm/Demangle/ItaniumDemangle.h#L5678)
 is implemented. This is a temporary fix for
 [#89914](https://github.com/llvm/llvm-project/issues/89914).

---
 libcxxabi/test/test_demangle.pass.cpp | 231 +++++++++++++-------------
 1 file changed, 114 insertions(+), 117 deletions(-)

diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index ab783cf9d96f22..6a8f49df58e4d0 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30137,6 +30137,7 @@ const char* cases[][2] =
     {"_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E0_clIiiEEDaS3_Qaa1CIDtfp_EELb1E", "auto void test7::f<int>()::'lambda0'<typename $T> requires C<T> && C<TL0_> (auto)::operator()<int, int>(auto) const requires C<decltype(fp)> && true"},
     {"_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E1_clIiiEEDaS3_Q1CIDtfp_EE", "auto void test7::f<int>()::'lambda1'<typename $T> requires C<T> && C<TL0_> (auto)::operator()<int, int>(auto) const requires C<decltype(fp)>"},
     {"_ZZN5test71fIiEEvvENKUlTyT0_E_clIiiEEDaS1_", "auto void test7::f<int>()::'lambda'<typename $T>(auto)::operator()<int, int>(auto) const"},
+    {"_ZN3FooIiE6methodITk4TrueIT_EiEEvS3_", "void Foo<int>::method<int>(T)"},
 
     // C++20 requires expressions, see https://github.com/itanium-cxx-abi/cxx-abi/issues/24.
     {"_Z1fIiEviQrqXcvT__EXfp_Xeqfp_cvS0__EXplcvS0__ELi1ER5SmallXmicvS0__ELi1ENXmlcvS0__ELi2ENR11SmallerThanILi1234EETS0_T1XIS0_ETNS3_4typeETS2_IiEQ11SmallerThanIS0_Li256EEE", "void f<int>(int) requires requires { (T)(); fp; fp == (T)(); {(T)() + 1} -> Small; {(T)() - 1} noexcept; {(T)() * 2} noexcept -> SmallerThan<1234>; typename T; typename X<T>; typename X<T>::type; typename X<int>; requires SmallerThan<T, 256>; }"},
@@ -30227,38 +30228,52 @@ struct FPLiteralCase {
 const unsigned NF = sizeof(fp_literal_cases) / sizeof(fp_literal_cases[0]);
 const unsigned NEF = sizeof(fp_literal_cases[0].expecting) / sizeof(fp_literal_cases[0].expecting[0]);
 
-
-const char* invalid_cases[] =
-{
+const char* invalid_cases[] = {
     "_ZIPPreEncode",
     "Agentt",
     "NSoERj5E=Y1[uM:ga",
     "Aon_PmKVPDk7?fg4XP5smMUL6;<WsI_mgbf23cCgsHbT<l8EE\0uVRkNOoXDrgdA4[8IU>Vl<>IL8ayHpiVDDDXTY;^o9;i",
-    "_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
+    "_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_"
+    "spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
     "3FooILdaaaaaaaaaaAAAAaaEE",
     "3FooILdaaaaaaaaaaaaaaEE",
 #if !LDBL_FP80
     "_ZN5test01hIfEEvRAcvjplstT_Le4001a000000000000000E_c",
 #endif
-	// The following test cases were found by libFuzzer+ASAN
-    "\x44\x74\x70\x74\x71\x75\x34\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37",
-    "\x4D\x41\x72\x63\x4E\x39\x44\x76\x72\x4D\x34\x44\x53\x4B\x6F\x44\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45*",
+    // The following test cases were found by libFuzzer+ASAN
+    "\x44\x74\x70\x74\x71\x75\x34\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
+    "\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37",
+    "\x4D\x41\x72\x63\x4E\x39\x44\x76\x72\x4D\x34\x44\x53\x4B\x6F\x44\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F"
+    "\x73\x70\x69\x45*",
     "\x41\x64\x6E\x32*",
     "\x43\x46\x41\x67\x73*",
-    "\x72\x3A\x4E\x53\x64\x45\x39\x4F\x52\x4E\x1F\x43\x34\x64\x54\x5F\x49\x31\x41\x63\x6C\x37\x2A\x4D\x41\x67\x73\x76\x43\x54\x35\x5F\x49\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x41\x47\x4C\x5A\x28\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69\x45\x5F\x63\x47\x61\x4C\x31\x4F\x4C\x33\x3E\x41\x4C\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x66\x41\x47\x4C\x5A\x28\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69\x45\x5F\x37\x41*",
+    "\x72\x3A\x4E\x53\x64\x45\x39\x4F\x52\x4E\x1F\x43\x34\x64\x54\x5F\x49\x31\x41\x63\x6C\x37\x2A\x4D\x41\x67\x73\x76"
+    "\x43\x54\x35\x5F\x49\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x41\x47\x4C\x5A\x28\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69"
+    "\x45\x5F\x63\x47\x61\x4C\x31\x4F\x4C\x33\x3E\x41\x4C\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x66\x41\x47\x4C\x5A\x28"
+    "\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69\x45\x5F\x37\x41*",
     "\x2D\x5F\x63\x47\x4F\x63\xD3",
-    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\xC3\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
-    "\x4C\x5A\x4C\x55\x6C\x4D\x41\x5F\x41\x67\x74\x71\x75\x34\x4D\x41\x64\x73\x4C\x44\x76\x72\x4D\x34\x44\x4B\x44\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6D\x73\x72\x53\x41\x6F\x41\x7B",
-    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x2C\x53\xF9\x5F\x70\x74\x70\x69\x45\xB4\xD3\x73\x9F\x2A\x37",
-    "\x4C\x5A\x4C\x55\x6C\x69\x4D\x73\x72\x53\x6F\x7A\x41\x5F\x41\x67\x74\x71\x75\x32\x4D\x41\x64\x73\x39\x28\x76\x72\x4D\x34\x44\x4B\x45\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6F\x45\x49\x6D\x1A\x4C\x53\x38\x6A\x7A\x5A",
+    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
+    "\xC3\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
+    "\x4C\x5A\x4C\x55\x6C\x4D\x41\x5F\x41\x67\x74\x71\x75\x34\x4D\x41\x64\x73\x4C\x44\x76\x72\x4D\x34\x44\x4B\x44\x54"
+    "\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6D\x73\x72\x53\x41\x6F\x41\x7B",
+    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
+    "\x2C\x53\xF9\x5F\x70\x74\x70\x69\x45\xB4\xD3\x73\x9F\x2A\x37",
+    "\x4C\x5A\x4C\x55\x6C\x69\x4D\x73\x72\x53\x6F\x7A\x41\x5F\x41\x67\x74\x71\x75\x32\x4D\x41\x64\x73\x39\x28\x76\x72"
+    "\x4D\x34\x44\x4B\x45\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6F\x45\x49\x6D\x1A\x4C\x53"
+    "\x38\x6A\x7A\x5A",
     "\x44\x74\x63*",
-    "\x44\x74\x71\x75\x35\x2A\xDF\x74\x44\x61\x73\x63\x35\x2A\x3B\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x63\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x33\x44\x76\x35",
-    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
-    "\x46\x44\x74\x70\x74\x71\x75\x32\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37\x72\x33\x8E\x3A\x29\x8E\x44\x35",
+    "\x44\x74\x71\x75\x35\x2A\xDF\x74\x44\x61\x73\x63\x35\x2A\x3B\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x63\x41\x72\x4D\x6E"
+    "\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x33\x44\x76\x35",
+    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
+    "\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
+    "\x46\x44\x74\x70\x74\x71\x75\x32\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F"
+    "\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37\x72\x33\x8E\x3A\x29\x8E\x44\x35",
     "_ZcvCiIJEEDvT__FFFFT_vT_v",
     "Z1JIJ1_T_EE3o00EUlT_E0",
     "___Z2i_D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D",
-    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_dZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_d",
+    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_"
+    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_dZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_"
+    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_d",
     "Z1 Z1 IJEEAcvZcvT_EcvT_T_",
     "T_IZaaIJEEAnaaaT_T__",
     "PT_IJPNT_IJEET_T_T_T_)J)JKE",
@@ -30290,124 +30305,106 @@ const char* invalid_cases[] =
 
 const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]);
 
-void test()
-{
-    std::size_t len = 0;
-    char* buf = nullptr;
-    bool failed = false;
-    for (unsigned i = 0; i < N; ++i)
-    {
-        int status;
-        char* demang =
-            __cxxabiv1::__cxa_demangle(cases[i][0], buf, &len, &status);
-        if (!demang || std::strcmp(demang, cases[i][1]) != 0)
-        {
-          std::fprintf(stderr, "ERROR demangling %s\n"
-                       "expected: %s\n"
-                       "got: %d,   %s\n",
-                       cases[i][0], cases[i][1], status,
-                       demang ? demang : "(null)");
-          failed = true;
-        }
-        if (demang)
-          buf = demang;
+void test() {
+  std::size_t len = 0;
+  char* buf = nullptr;
+  bool failed = false;
+  for (unsigned i = 0; i < N; ++i) {
+    int status;
+    char* demang = __cxxabiv1::__cxa_demangle(cases[i][0], buf, &len, &status);
+    if (!demang || std::strcmp(demang, cases[i][1]) != 0) {
+      std::fprintf(stderr,
+                   "ERROR demangling %s\n"
+                   "expected: %s\n"
+                   "got: %d,   %s\n",
+                   cases[i][0], cases[i][1], status, demang ? demang : "(null)");
+      failed = true;
     }
-    free(buf);
-    assert(!failed && "demangle failed");
+    if (demang)
+      buf = demang;
+  }
+  free(buf);
+  assert(!failed && "demangle failed");
 }
 
-void test_invalid_cases()
-{
-    std::size_t len = 0;
-    char* buf = nullptr;
-    bool passed = false;
-    for (unsigned i = 0; i < NI; ++i)
-    {
-        int status;
-        char* demang =
-            __cxxabiv1::__cxa_demangle(invalid_cases[i], buf, &len, &status);
-        if (status != -2)
-        {
-            std::printf("%s should be invalid but is not\n", invalid_cases[i]);
-            std::printf("Got: %d, %s\n", status, demang ? demang : "(null)");
-            passed = true;
-        }
-        if (demang)
-          buf = demang;
+void test_invalid_cases() {
+  std::size_t len = 0;
+  char* buf = nullptr;
+  bool passed = false;
+  for (unsigned i = 0; i < NI; ++i) {
+    int status;
+    char* demang = __cxxabiv1::__cxa_demangle(invalid_cases[i], buf, &len, &status);
+    if (status != -2) {
+      std::printf("%s should be invalid but is not\n", invalid_cases[i]);
+      std::printf("Got: %d, %s\n", status, demang ? demang : "(null)");
+      passed = true;
     }
-    free(buf);
-    assert(!passed && "demangle did not fail");
+    if (demang)
+      buf = demang;
+  }
+  free(buf);
+  assert(!passed && "demangle did not fail");
 }
 
-const char *xfail_cases[] = {
+const char* xfail_cases[] = {
     // FIXME: Why does clang generate the "cp" expr?
     "_ZN5test11bIsEEDTcp3foocvT__EEES1_",
 };
 
 const size_t num_xfails = sizeof(xfail_cases) / sizeof(xfail_cases[0]);
 
-void test_xfail_cases()
-{
-    std::size_t len = 0;
-    char* buf = nullptr;
-    for (std::size_t i = 0; i < num_xfails; ++i)
-    {
-        int status;
-        char* demang = __cxxabiv1::__cxa_demangle(xfail_cases[i], buf, &len, &status);
-        if (status != -2)
-        {
-            std::printf("%s was documented as xfail but passed\n", xfail_cases[i]);
-            std::printf("Got status = %d\n", status);
-            assert(status == -2);
-        }
-        else
-        {
-            buf = demang;
-        }
+void test_xfail_cases() {
+  std::size_t len = 0;
+  char* buf = nullptr;
+  for (std::size_t i = 0; i < num_xfails; ++i) {
+    int status;
+    char* demang = __cxxabiv1::__cxa_demangle(xfail_cases[i], buf, &len, &status);
+    if (status != -2) {
+      std::printf("%s was documented as xfail but passed\n", xfail_cases[i]);
+      std::printf("Got status = %d\n", status);
+      assert(status == -2);
+    } else {
+      buf = demang;
     }
-    free(buf);
+  }
+  free(buf);
 }
 
-void testFPLiterals()
-{
-    std::size_t len = 0;
-    char* buf = nullptr;
-    for (unsigned i = 0; i < NF; ++i)
-    {
-        FPLiteralCase *fpCase = fp_literal_cases+i;
-        int status;
-        char* demang = __cxxabiv1::__cxa_demangle(fpCase->mangled, buf, &len, &status);
-        if (demang == 0)
-        {
-            std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
-            std::printf("Got instead: NULL, %d\n", status);
-            assert(false);
-            continue;
-        }
-        std::string *e_beg = fpCase->expecting;
-        std::string *e_end = fpCase->expecting + NEF;
-        if (std::find(e_beg, e_end, demang) == e_end)
-        {
-            std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
-            std::printf("Got instead: %s\n", demang);
-            assert(false);
-            continue;
-        }
-        buf = demang;
+void testFPLiterals() {
+  std::size_t len = 0;
+  char* buf = nullptr;
+  for (unsigned i = 0; i < NF; ++i) {
+    FPLiteralCase* fpCase = fp_literal_cases + i;
+    int status;
+    char* demang = __cxxabiv1::__cxa_demangle(fpCase->mangled, buf, &len, &status);
+    if (demang == 0) {
+      std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
+      std::printf("Got instead: NULL, %d\n", status);
+      assert(false);
+      continue;
+    }
+    std::string* e_beg = fpCase->expecting;
+    std::string* e_end = fpCase->expecting + NEF;
+    if (std::find(e_beg, e_end, demang) == e_end) {
+      std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
+      std::printf("Got instead: %s\n", demang);
+      assert(false);
+      continue;
     }
-    free(buf);
+    buf = demang;
+  }
+  free(buf);
 }
 
-int main(int, char**)
-{
-    std::printf("Testing %d symbols.\n", N);
-    {
-        timer t;
-        test();
-        test_invalid_cases();
-        test_xfail_cases();
-        testFPLiterals();
-    }
+int main(int, char**) {
+  std::printf("Testing %d symbols.\n", N);
+  {
+    timer t;
+    test();
+    test_invalid_cases();
+    test_xfail_cases();
+    testFPLiterals();
+  }
 #if 0
     std::string input;
     while (std::cin)
@@ -30443,5 +30440,5 @@ int main(int, char**)
     }
 #endif
 
-    return 0;
+  return 0;
 }

>From 3d2bcf06e266ba36f404210111b7ab78eb870701 Mon Sep 17 00:00:00 2001
From: Viktoriia Bakalova <bakalova at google.com>
Date: Wed, 11 Sep 2024 16:04:32 +0000
Subject: [PATCH 3/3] Undo formatting

---
 libcxxabi/test/test_demangle.pass.cpp | 231 +++++++++++++-------------
 1 file changed, 117 insertions(+), 114 deletions(-)

diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 6a8f49df58e4d0..ab783cf9d96f22 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -30137,7 +30137,6 @@ const char* cases[][2] =
     {"_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E0_clIiiEEDaS3_Qaa1CIDtfp_EELb1E", "auto void test7::f<int>()::'lambda0'<typename $T> requires C<T> && C<TL0_> (auto)::operator()<int, int>(auto) const requires C<decltype(fp)> && true"},
     {"_ZZN5test71fIiEEvvENKUlTyQaa1CIT_E1CITL0__ET0_E1_clIiiEEDaS3_Q1CIDtfp_EE", "auto void test7::f<int>()::'lambda1'<typename $T> requires C<T> && C<TL0_> (auto)::operator()<int, int>(auto) const requires C<decltype(fp)>"},
     {"_ZZN5test71fIiEEvvENKUlTyT0_E_clIiiEEDaS1_", "auto void test7::f<int>()::'lambda'<typename $T>(auto)::operator()<int, int>(auto) const"},
-    {"_ZN3FooIiE6methodITk4TrueIT_EiEEvS3_", "void Foo<int>::method<int>(T)"},
 
     // C++20 requires expressions, see https://github.com/itanium-cxx-abi/cxx-abi/issues/24.
     {"_Z1fIiEviQrqXcvT__EXfp_Xeqfp_cvS0__EXplcvS0__ELi1ER5SmallXmicvS0__ELi1ENXmlcvS0__ELi2ENR11SmallerThanILi1234EETS0_T1XIS0_ETNS3_4typeETS2_IiEQ11SmallerThanIS0_Li256EEE", "void f<int>(int) requires requires { (T)(); fp; fp == (T)(); {(T)() + 1} -> Small; {(T)() - 1} noexcept; {(T)() * 2} noexcept -> SmallerThan<1234>; typename T; typename X<T>; typename X<T>::type; typename X<int>; requires SmallerThan<T, 256>; }"},
@@ -30228,52 +30227,38 @@ struct FPLiteralCase {
 const unsigned NF = sizeof(fp_literal_cases) / sizeof(fp_literal_cases[0]);
 const unsigned NEF = sizeof(fp_literal_cases[0].expecting) / sizeof(fp_literal_cases[0].expecting[0]);
 
-const char* invalid_cases[] = {
+
+const char* invalid_cases[] =
+{
     "_ZIPPreEncode",
     "Agentt",
     "NSoERj5E=Y1[uM:ga",
     "Aon_PmKVPDk7?fg4XP5smMUL6;<WsI_mgbf23cCgsHbT<l8EE\0uVRkNOoXDrgdA4[8IU>Vl<>IL8ayHpiVDDDXTY;^o9;i",
-    "_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_"
-    "spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
+    "_ZNSt16allocator_traitsISaIN4llvm3sys2fs18directory_iteratorEEE9constructIS3_IS3_EEEDTcl12_S_constructfp_fp0_spcl7forwardIT0_Efp1_EEERS4_PT_DpOS7_",
     "3FooILdaaaaaaaaaaAAAAaaEE",
     "3FooILdaaaaaaaaaaaaaaEE",
 #if !LDBL_FP80
     "_ZN5test01hIfEEvRAcvjplstT_Le4001a000000000000000E_c",
 #endif
-    // The following test cases were found by libFuzzer+ASAN
-    "\x44\x74\x70\x74\x71\x75\x34\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
-    "\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37",
-    "\x4D\x41\x72\x63\x4E\x39\x44\x76\x72\x4D\x34\x44\x53\x4B\x6F\x44\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F"
-    "\x73\x70\x69\x45*",
+	// The following test cases were found by libFuzzer+ASAN
+    "\x44\x74\x70\x74\x71\x75\x34\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37",
+    "\x4D\x41\x72\x63\x4E\x39\x44\x76\x72\x4D\x34\x44\x53\x4B\x6F\x44\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45*",
     "\x41\x64\x6E\x32*",
     "\x43\x46\x41\x67\x73*",
-    "\x72\x3A\x4E\x53\x64\x45\x39\x4F\x52\x4E\x1F\x43\x34\x64\x54\x5F\x49\x31\x41\x63\x6C\x37\x2A\x4D\x41\x67\x73\x76"
-    "\x43\x54\x35\x5F\x49\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x41\x47\x4C\x5A\x28\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69"
-    "\x45\x5F\x63\x47\x61\x4C\x31\x4F\x4C\x33\x3E\x41\x4C\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x66\x41\x47\x4C\x5A\x28"
-    "\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69\x45\x5F\x37\x41*",
+    "\x72\x3A\x4E\x53\x64\x45\x39\x4F\x52\x4E\x1F\x43\x34\x64\x54\x5F\x49\x31\x41\x63\x6C\x37\x2A\x4D\x41\x67\x73\x76\x43\x54\x35\x5F\x49\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x41\x47\x4C\x5A\x28\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69\x45\x5F\x63\x47\x61\x4C\x31\x4F\x4C\x33\x3E\x41\x4C\x4B\x4C\x55\x6C\x73\x4C\x38\x64\x43\x66\x41\x47\x4C\x5A\x28\x4F\x41\x6E\x77\x5F\x53\x6F\x70\x69\x45\x5F\x37\x41*",
     "\x2D\x5F\x63\x47\x4F\x63\xD3",
-    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
-    "\xC3\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
-    "\x4C\x5A\x4C\x55\x6C\x4D\x41\x5F\x41\x67\x74\x71\x75\x34\x4D\x41\x64\x73\x4C\x44\x76\x72\x4D\x34\x44\x4B\x44\x54"
-    "\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6D\x73\x72\x53\x41\x6F\x41\x7B",
-    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
-    "\x2C\x53\xF9\x5F\x70\x74\x70\x69\x45\xB4\xD3\x73\x9F\x2A\x37",
-    "\x4C\x5A\x4C\x55\x6C\x69\x4D\x73\x72\x53\x6F\x7A\x41\x5F\x41\x67\x74\x71\x75\x32\x4D\x41\x64\x73\x39\x28\x76\x72"
-    "\x4D\x34\x44\x4B\x45\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6F\x45\x49\x6D\x1A\x4C\x53"
-    "\x38\x6A\x7A\x5A",
+    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\xC3\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
+    "\x4C\x5A\x4C\x55\x6C\x4D\x41\x5F\x41\x67\x74\x71\x75\x34\x4D\x41\x64\x73\x4C\x44\x76\x72\x4D\x34\x44\x4B\x44\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6D\x73\x72\x53\x41\x6F\x41\x7B",
+    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x2C\x53\xF9\x5F\x70\x74\x70\x69\x45\xB4\xD3\x73\x9F\x2A\x37",
+    "\x4C\x5A\x4C\x55\x6C\x69\x4D\x73\x72\x53\x6F\x7A\x41\x5F\x41\x67\x74\x71\x75\x32\x4D\x41\x64\x73\x39\x28\x76\x72\x4D\x34\x44\x4B\x45\x54\x6E\x61\x37\x47\x77\x78\x38\x43\x27\x41\x5F\x73\x70\x69\x45\x6F\x45\x49\x6D\x1A\x4C\x53\x38\x6A\x7A\x5A",
     "\x44\x74\x63*",
-    "\x44\x74\x71\x75\x35\x2A\xDF\x74\x44\x61\x73\x63\x35\x2A\x3B\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x63\x41\x72\x4D\x6E"
-    "\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x33\x44\x76\x35",
-    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64"
-    "\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
-    "\x46\x44\x74\x70\x74\x71\x75\x32\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F"
-    "\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37\x72\x33\x8E\x3A\x29\x8E\x44\x35",
+    "\x44\x74\x71\x75\x35\x2A\xDF\x74\x44\x61\x73\x63\x35\x2A\x3B\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x63\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x33\x44\x76\x35",
+    "\x44\x74\x70\x74\x71\x75\x32\x43\x41\x38\x65\x6E\x9B\x72\x4D\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x38\xD3\x73\x9E\x2A\x37",
+    "\x46\x44\x74\x70\x74\x71\x75\x32\x43\x41\x72\x4D\x6E\x65\x34\x9F\xC1\x43\x41\x72\x4D\x6E\x77\x38\x9A\x8E\x44\x6F\x64\x6C\x53\xF9\x5F\x70\x74\x70\x69\x45\x34\xD3\x73\x9E\x2A\x37\x72\x33\x8E\x3A\x29\x8E\x44\x35",
     "_ZcvCiIJEEDvT__FFFFT_vT_v",
     "Z1JIJ1_T_EE3o00EUlT_E0",
     "___Z2i_D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D1D",
-    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_"
-    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_dZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_"
-    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_d",
+    "ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_dZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_ZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIZcvSdIDv_Dv_Dv_Dv_Dv_d",
     "Z1 Z1 IJEEAcvZcvT_EcvT_T_",
     "T_IZaaIJEEAnaaaT_T__",
     "PT_IJPNT_IJEET_T_T_T_)J)JKE",
@@ -30305,106 +30290,124 @@ const char* invalid_cases[] = {
 
 const unsigned NI = sizeof(invalid_cases) / sizeof(invalid_cases[0]);
 
-void test() {
-  std::size_t len = 0;
-  char* buf = nullptr;
-  bool failed = false;
-  for (unsigned i = 0; i < N; ++i) {
-    int status;
-    char* demang = __cxxabiv1::__cxa_demangle(cases[i][0], buf, &len, &status);
-    if (!demang || std::strcmp(demang, cases[i][1]) != 0) {
-      std::fprintf(stderr,
-                   "ERROR demangling %s\n"
-                   "expected: %s\n"
-                   "got: %d,   %s\n",
-                   cases[i][0], cases[i][1], status, demang ? demang : "(null)");
-      failed = true;
+void test()
+{
+    std::size_t len = 0;
+    char* buf = nullptr;
+    bool failed = false;
+    for (unsigned i = 0; i < N; ++i)
+    {
+        int status;
+        char* demang =
+            __cxxabiv1::__cxa_demangle(cases[i][0], buf, &len, &status);
+        if (!demang || std::strcmp(demang, cases[i][1]) != 0)
+        {
+          std::fprintf(stderr, "ERROR demangling %s\n"
+                       "expected: %s\n"
+                       "got: %d,   %s\n",
+                       cases[i][0], cases[i][1], status,
+                       demang ? demang : "(null)");
+          failed = true;
+        }
+        if (demang)
+          buf = demang;
     }
-    if (demang)
-      buf = demang;
-  }
-  free(buf);
-  assert(!failed && "demangle failed");
+    free(buf);
+    assert(!failed && "demangle failed");
 }
 
-void test_invalid_cases() {
-  std::size_t len = 0;
-  char* buf = nullptr;
-  bool passed = false;
-  for (unsigned i = 0; i < NI; ++i) {
-    int status;
-    char* demang = __cxxabiv1::__cxa_demangle(invalid_cases[i], buf, &len, &status);
-    if (status != -2) {
-      std::printf("%s should be invalid but is not\n", invalid_cases[i]);
-      std::printf("Got: %d, %s\n", status, demang ? demang : "(null)");
-      passed = true;
+void test_invalid_cases()
+{
+    std::size_t len = 0;
+    char* buf = nullptr;
+    bool passed = false;
+    for (unsigned i = 0; i < NI; ++i)
+    {
+        int status;
+        char* demang =
+            __cxxabiv1::__cxa_demangle(invalid_cases[i], buf, &len, &status);
+        if (status != -2)
+        {
+            std::printf("%s should be invalid but is not\n", invalid_cases[i]);
+            std::printf("Got: %d, %s\n", status, demang ? demang : "(null)");
+            passed = true;
+        }
+        if (demang)
+          buf = demang;
     }
-    if (demang)
-      buf = demang;
-  }
-  free(buf);
-  assert(!passed && "demangle did not fail");
+    free(buf);
+    assert(!passed && "demangle did not fail");
 }
 
-const char* xfail_cases[] = {
+const char *xfail_cases[] = {
     // FIXME: Why does clang generate the "cp" expr?
     "_ZN5test11bIsEEDTcp3foocvT__EEES1_",
 };
 
 const size_t num_xfails = sizeof(xfail_cases) / sizeof(xfail_cases[0]);
 
-void test_xfail_cases() {
-  std::size_t len = 0;
-  char* buf = nullptr;
-  for (std::size_t i = 0; i < num_xfails; ++i) {
-    int status;
-    char* demang = __cxxabiv1::__cxa_demangle(xfail_cases[i], buf, &len, &status);
-    if (status != -2) {
-      std::printf("%s was documented as xfail but passed\n", xfail_cases[i]);
-      std::printf("Got status = %d\n", status);
-      assert(status == -2);
-    } else {
-      buf = demang;
+void test_xfail_cases()
+{
+    std::size_t len = 0;
+    char* buf = nullptr;
+    for (std::size_t i = 0; i < num_xfails; ++i)
+    {
+        int status;
+        char* demang = __cxxabiv1::__cxa_demangle(xfail_cases[i], buf, &len, &status);
+        if (status != -2)
+        {
+            std::printf("%s was documented as xfail but passed\n", xfail_cases[i]);
+            std::printf("Got status = %d\n", status);
+            assert(status == -2);
+        }
+        else
+        {
+            buf = demang;
+        }
     }
-  }
-  free(buf);
+    free(buf);
 }
 
-void testFPLiterals() {
-  std::size_t len = 0;
-  char* buf = nullptr;
-  for (unsigned i = 0; i < NF; ++i) {
-    FPLiteralCase* fpCase = fp_literal_cases + i;
-    int status;
-    char* demang = __cxxabiv1::__cxa_demangle(fpCase->mangled, buf, &len, &status);
-    if (demang == 0) {
-      std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
-      std::printf("Got instead: NULL, %d\n", status);
-      assert(false);
-      continue;
-    }
-    std::string* e_beg = fpCase->expecting;
-    std::string* e_end = fpCase->expecting + NEF;
-    if (std::find(e_beg, e_end, demang) == e_end) {
-      std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
-      std::printf("Got instead: %s\n", demang);
-      assert(false);
-      continue;
+void testFPLiterals()
+{
+    std::size_t len = 0;
+    char* buf = nullptr;
+    for (unsigned i = 0; i < NF; ++i)
+    {
+        FPLiteralCase *fpCase = fp_literal_cases+i;
+        int status;
+        char* demang = __cxxabiv1::__cxa_demangle(fpCase->mangled, buf, &len, &status);
+        if (demang == 0)
+        {
+            std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
+            std::printf("Got instead: NULL, %d\n", status);
+            assert(false);
+            continue;
+        }
+        std::string *e_beg = fpCase->expecting;
+        std::string *e_end = fpCase->expecting + NEF;
+        if (std::find(e_beg, e_end, demang) == e_end)
+        {
+            std::printf("%s -> %s\n", fpCase->mangled, fpCase->expecting[0].c_str());
+            std::printf("Got instead: %s\n", demang);
+            assert(false);
+            continue;
+        }
+        buf = demang;
     }
-    buf = demang;
-  }
-  free(buf);
+    free(buf);
 }
 
-int main(int, char**) {
-  std::printf("Testing %d symbols.\n", N);
-  {
-    timer t;
-    test();
-    test_invalid_cases();
-    test_xfail_cases();
-    testFPLiterals();
-  }
+int main(int, char**)
+{
+    std::printf("Testing %d symbols.\n", N);
+    {
+        timer t;
+        test();
+        test_invalid_cases();
+        test_xfail_cases();
+        testFPLiterals();
+    }
 #if 0
     std::string input;
     while (std::cin)
@@ -30440,5 +30443,5 @@ int main(int, char**) {
     }
 #endif
 
-  return 0;
+    return 0;
 }



More information about the libcxx-commits mailing list