Skip to content

[ItaniumDemangle][test] Turn ItaniumDemangle tests into LLVM unit-tests #137947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

Michael137
Copy link
Member

This patch turns the libcxxabi/test/test_demangle.pass.cpp into gtest unit-tests in llvm/unittests/Demangle. The main motivation for this is #137793, where we want to re-use the test-cases from the ItaniumDemangler to test our OutputBuffer implementation.

libcxxabi/test/test_demangle.pass.cpp now only tests the __cxa_demangle API surface, not the underlying ItaniumDemangle implementation.

@Michael137 Michael137 requested review from zygoloid and ldionne April 30, 2025 09:59
@Michael137 Michael137 requested a review from a team as a code owner April 30, 2025 09:59
@llvmbot llvmbot added the libc++abi libc++abi C++ Runtime Library. Not libc++. label Apr 30, 2025
@Michael137 Michael137 changed the title [ItaniumDemangle][test] Turn ItaniumDemangle tests in LLVM unit-tests [ItaniumDemangle][test] Turn ItaniumDemangle tests into LLVM unit-tests Apr 30, 2025
@Michael137 Michael137 requested a review from labath April 30, 2025 10:00
@llvmbot
Copy link
Member

llvmbot commented Apr 30, 2025

@llvm/pr-subscribers-libcxxabi

Author: Michael Buch (Michael137)

Changes

This patch turns the libcxxabi/test/test_demangle.pass.cpp into gtest unit-tests in llvm/unittests/Demangle. The main motivation for this is #137793, where we want to re-use the test-cases from the ItaniumDemangler to test our OutputBuffer implementation.

libcxxabi/test/test_demangle.pass.cpp now only tests the __cxa_demangle API surface, not the underlying ItaniumDemangle implementation.


Patch is 10.20 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/137947.diff

4 Files Affected:

  • (modified) libcxxabi/src/demangle/README.txt (+3-4)
  • (modified) libcxxabi/test/test_demangle.pass.cpp (+46-30405)
  • (added) llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc (+30219)
  • (modified) llvm/unittests/Demangle/ItaniumDemangleTest.cpp (+178)
diff --git a/libcxxabi/src/demangle/README.txt b/libcxxabi/src/demangle/README.txt
index c3f49e57b8d16..23c8715725187 100644
--- a/libcxxabi/src/demangle/README.txt
+++ b/libcxxabi/src/demangle/README.txt
@@ -52,10 +52,9 @@ shared demangler library.
 Testing
 -------
 
-The tests are split up between libcxxabi/test/{unit,}test_demangle.cpp, and
-llvm/unittests/Demangle. The llvm directory should only get tests for stuff not
-included in the core library. In the future though, we should probably move all
-the tests to LLVM.
+The main ItaniumDemangle test-siute lives in llvm/unittests/Demangle/.
+The libcxxabi/test/{unit,}test_demangle.cpp test tests basic functionality
+of __cxa_demangle.
 
 It is also a really good idea to run libFuzzer after non-trivial changes, see
 libcxxabi/fuzz/cxa_demangle_fuzzer.cpp and https://llvm.org/docs/LibFuzzer.html.
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 343885da3017a..52bc7879ccd16 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// Tests for ItaniumDemangle live in llvm/unittests/Demangle
+
 // This test is too big for most embedded devices.
 // XFAIL: LIBCXX-PICOLIBC-FIXME
 
@@ -24,30357 +26,27 @@
 #include <cxxabi.h>
 #include <string>
 
-// Is long double fp80?  (Only x87 extended double has 64-bit mantissa)
-#define LDBL_FP80 (__LDBL_MANT_DIG__ == 64)
-// Is long double fp128?
-#define LDBL_FP128 (__LDBL_MANT_DIG__ == 113)
-
-const char* cases[][2] = {
-    // clang-format off
-    {"_Z1A", "A"},
-    {"_Z1Av", "A()"},
-    {"_Z1A1B1C", "A(B, C)"},
-    {"_Z1fDB3_", "f(_BitInt(3))"},
-    {"_Z1fDU10_", "f(unsigned _BitInt(10))"},
-    {"_Z1fIfEvDUstPT__", "void f<float>(unsigned _BitInt(sizeof (float*)))"},
-    {"_Z1fIiEvDBstPT__", "void f<int>(_BitInt(sizeof (int*)))"},
-    {"_Z4testI1A1BE1Cv", "C test<A, B>()"},
-    {"_Z4testI1A1BET0_T_S3_", "B test<A, B>(A, A)"},
-    {"_ZN1SgtEi", "S::operator>(int)"},
-    {"_ZrsI1QEiT_i", "int operator>><Q>(Q, int)"},
-    {"_ZN13dyldbootstrap5startEPK12macho_headeriPPKcl", "dyldbootstrap::start(macho_header const*, int, char const**, long)"},
-    {"_ZN4dyld17getExecutablePathEv", "dyld::getExecutablePath()"},
-    {"_ZN4dyld22mainExecutablePreboundEv", "dyld::mainExecutablePrebound()"},
-    {"_ZN4dyld14mainExecutableEv", "dyld::mainExecutable()"},
-    {"_ZN4dyld21findImageByMachHeaderEPK11mach_header", "dyld::findImageByMachHeader(mach_header const*)"},
-    {"_ZN4dyld26findImageContainingAddressEPKv", "dyld::findImageContainingAddress(void const*)"},
-    {"_ZN4dyld17clearErrorMessageEv", "dyld::clearErrorMessage()"},
-    {"_ZN4dyld15getErrorMessageEv", "dyld::getErrorMessage()"},
-    {"_ZN4dyld24registerUndefinedHandlerEPFvPKcE", "dyld::registerUndefinedHandler(void (*)(char const*))"},
-    {"_ZN4dyld19openSharedCacheFileEv", "dyld::openSharedCacheFile()"},
-    {"_ZN4dyld15setErrorMessageEPKc", "dyld::setErrorMessage(char const*)"},
-    {"_ZN4dyld22registerRemoveCallbackEPFvPK11mach_headerlE", "dyld::registerRemoveCallback(void (*)(mach_header const*, long))"},
-    {"_ZN4dyld13inSharedCacheEPKc", "dyld::inSharedCache(char const*)"},
-    {"_ZN4dyld15runInitializersEP11ImageLoader", "dyld::runInitializers(ImageLoader*)"},
-    {"_ZN4dyld27findCoalescedExportedSymbolEPKcPPKN11ImageLoader6SymbolEPPKS2_", "dyld::findCoalescedExportedSymbol(char const*, ImageLoader::Symbol const**, ImageLoader const**)"},
-    {"_ZN4dyld22flatFindExportedSymbolEPKcPPKN11ImageLoader6SymbolEPPKS2_", "dyld::flatFindExportedSymbol(char const*, ImageLoader::Symbol const**, ImageLoader const**)"},
-    {"_ZN4dyld15findLoadedImageERK4stat", "dyld::findLoadedImage(stat const&)"},
-    {"_ZN4dyld24initializeMainExecutableEv", "dyld::initializeMainExecutable()"},
-    {"_ZN4dyld4warnEPKcz", "dyld::warn(char const*, ...)"},
-    {"_ZN4dyld29processDyldEnvironmentVaribleEPKcS1_", "dyld::processDyldEnvironmentVarible(char const*, char const*)"},
-    {"_ZN4dyld3logEPKcz", "dyld::log(char const*, ...)"},
-    {"_ZN4dyld6throwfEPKcz", "dyld::throwf(char const*, ...)"},
-    {"_ZN4dyld9mkstringfEPKcz", "dyld::mkstringf(char const*, ...)"},
-    {"_ZN4dyld14addMappedRangeEP11ImageLoadermm", "dyld::addMappedRange(ImageLoader*, unsigned long, unsigned long)"},
-    {"_Z28coresymbolication_load_imageP25CSCppDyldSharedMemoryPagePK11ImageLoadery", "coresymbolication_load_image(CSCppDyldSharedMemoryPage*, ImageLoader const*, unsigned long long)"},
-    {"_Z30coresymbolication_unload_imageP25CSCppDyldSharedMemoryPagePK11ImageLoader", "coresymbolication_unload_image(CSCppDyldSharedMemoryPage*, ImageLoader const*)"},
-    {"_ZN4dyld18getCoalescedImagesEPP11ImageLoader", "dyld::getCoalescedImages(ImageLoader**)"},
-    {"_ZN4dyld25findImageContainingSymbolEPKv", "dyld::findImageContainingSymbol(void const*)"},
-    {"_ZN4dyld19registerAddCallbackEPFvPK11mach_headerlE", "dyld::registerAddCallback(void (*)(mach_header const*, long))"},
-    {"_ZN4dyld14forEachImageDoEPFvP11ImageLoaderPvES2_", "dyld::forEachImageDo(void (*)(ImageLoader*, void*), void*)"},
-    {"_ZN4dyld15getIndexedImageEj", "dyld::getIndexedImage(unsigned int)"},
-    {"_ZN4dyld13getImageCountEv", "dyld::getImageCount()"},
-    {"_ZN4dyld10validImageEPK11ImageLoader", "dyld::validImage(ImageLoader const*)"},
-    {"_ZN4dyld30flatFindExportedSymbolWithHintEPKcS1_PPKN11ImageLoader6SymbolEPPKS2_", "dyld::flatFindExportedSymbolWithHint(char const*, char const*, ImageLoader::Symbol const**, ImageLoader const**)"},
-    {"_ZN4dyld14loadFromMemoryEPKhyPKc", "dyld::loadFromMemory(unsigned char const*, unsigned long long, char const*)"},
-    {"_ZN4dyld36registerImageStateBatchChangeHandlerE17dyld_image_statesPFPKcS0_jPK15dyld_image_infoE", "dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*))"},
-    {"_ZN4dyld37registerImageStateSingleChangeHandlerE17dyld_image_statesPFPKcS0_jPK15dyld_image_infoE", "dyld::registerImageStateSingleChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*))"},
-    {"_ZN4dyld4haltEPKc", "dyld::halt(char const*)"},
-    {"_ZN4dyld18fastBindLazySymbolEPP11ImageLoaderm", "dyld::fastBindLazySymbol(ImageLoader**, unsigned long)"},
-    {"_ZN4dyld14bindLazySymbolEPK11mach_headerPm", "dyld::bindLazySymbol(mach_header const*, unsigned long*)"},
-    {"_ZN4dyld14runTerminatorsEPv", "dyld::runTerminators(void*)"},
-    {"_ZN4dyld11removeImageEP11ImageLoader", "dyld::removeImage(ImageLoader*)"},
-    {"_ZN4dyld20garbageCollectImagesEv", "dyld::garbageCollectImages()"},
-    {"_ZN4dyld9preflightEP11ImageLoaderRKNS0_10RPathChainE", "dyld::preflight(ImageLoader*, ImageLoader::RPathChain const&)"},
-    {"_ZN4dyld4linkEP11ImageLoaderbRKNS0_10RPathChainE", "dyld::link(ImageLoader*, bool, ImageLoader::RPathChain const&)"},
-    {"_ZN4dyld10cloneImageEP11ImageLoader", "dyld::cloneImage(ImageLoader*)"},
-    {"_ZN4dyld4loadEPKcRKNS_11LoadContextE", "dyld::load(char const*, dyld::LoadContext const&)"},
-    {"_ZN4dyld5_mainEPK12macho_headermiPPKcS5_S5_", "dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**)"},
-    {"_ZNSt6vectorIN4dyld13RegisteredDOFESaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE", "std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>::erase(__gnu_cxx::__normal_iterator<dyld::RegisteredDOF*, std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>>)"},
-    {"_ZNSt12_Vector_baseIPKcSaIS1_EED2Ev", "std::_Vector_base<char const*, std::allocator<char const*>>::~_Vector_base()"},
-    {"_ZNSt6vectorIPKcSaIS1_EED2Ev", "std::vector<char const*, std::allocator<char const*>>::~vector()"},
-    {"_ZNSt12_Vector_baseIPFPKc17dyld_image_statesjPK15dyld_image_infoESaIS7_EED2Ev", "std::_Vector_base<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), std::allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>>::~_Vector_base()"},
-    {"_ZNSt6vectorIPFPKc17dyld_image_statesjPK15dyld_image_infoESaIS7_EED2Ev", "std::vector<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), std::allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>>::~vector()"},
-    {"_ZNSt12_Vector_baseIPFvPK11mach_headerlESaIS4_EED2Ev", "std::_Vector_base<void (*)(mach_header const*, long), std::allocator<void (*)(mach_header const*, long)>>::~_Vector_base()"},
-    {"_ZNSt6vectorIPFvPK11mach_headerlESaIS4_EED2Ev", "std::vector<void (*)(mach_header const*, long), std::allocator<void (*)(mach_header const*, long)>>::~vector()"},
-    {"_ZNSt12_Vector_baseIN4dyld13RegisteredDOFESaIS1_EED2Ev", "std::_Vector_base<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>::~_Vector_base()"},
-    {"_ZNSt6vectorIN4dyld13RegisteredDOFESaIS1_EED2Ev", "std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>::~vector()"},
-    {"_ZNSt12_Vector_baseIP11ImageLoaderSaIS1_EED2Ev", "std::_Vector_base<ImageLoader*, std::allocator<ImageLoader*>>::~_Vector_base()"},
-    {"_ZNSt6vectorIP11ImageLoaderSaIS1_EED2Ev", "std::vector<ImageLoader*, std::allocator<ImageLoader*>>::~vector()"},
-    {"_ZN9__gnu_cxx13new_allocatorIPFPKc17dyld_image_statesjPK15dyld_image_infoEE8allocateEmPKv", "__gnu_cxx::new_allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>::allocate(unsigned long, void const*)"},
-    {"_ZN9__gnu_cxx13new_allocatorIPFvPK11mach_headerlEE8allocateEmPKv", "__gnu_cxx::new_allocator<void (*)(mach_header const*, long)>::allocate(unsigned long, void const*)"},
-    {"_ZN9__gnu_cxx13new_allocatorIPKcE8allocateEmPKv", "__gnu_cxx::new_allocator<char const*>::allocate(unsigned long, void const*)"},
-    {"_ZN9__gnu_cxx13new_allocatorIP11ImageLoaderE8allocateEmPKv", "__gnu_cxx::new_allocator<ImageLoader*>::allocate(unsigned long, void const*)"},
-    {"_ZN9__gnu_cxx13new_allocatorIN4dyld13RegisteredDOFEE8allocateEmPKv", "__gnu_cxx::new_allocator<dyld::RegisteredDOF>::allocate(unsigned long, void const*)"},
-    {"_ZNSt6vectorIN4dyld13RegisteredDOFESaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_", "std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>::_M_insert_aux(__gnu_cxx::__normal_iterator<dyld::RegisteredDOF*, std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>>, dyld::RegisteredDOF const&)"},
-    {"_ZNSt6vectorIN4dyld13RegisteredDOFESaIS1_EE9push_backERKS1_", "std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>::push_back(dyld::RegisteredDOF const&)"},
-    {"_ZSt18uninitialized_copyIPPFPKc17dyld_image_statesjPK15dyld_image_infoES8_ET0_T_SA_S9_", "char const* (**std::uninitialized_copy<char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*), char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*)>(char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*), char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*), char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*)))(dyld_image_states, unsigned int, dyld_image_info const*)"},
-    {"_ZSt18uninitialized_copyIPPFvPK11mach_headerlES5_ET0_T_S7_S6_", "void (**std::uninitialized_copy<void (**)(mach_header const*, long), void (**)(mach_header const*, long)>(void (**)(mach_header const*, long), void (**)(mach_header const*, long), void (**)(mach_header const*, long)))(mach_header const*, long)"},
-    {"_ZSt18uninitialized_copyIPPKcS2_ET0_T_S4_S3_", "char const** std::uninitialized_copy<char const**, char const**>(char const**, char const**, char const**)"},
-    {"_ZNSt15__copy_backwardILb1ESt26random_access_iterator_tagE8__copy_bIPFPKc17dyld_image_statesjPK15dyld_image_infoEEEPT_PKSB_SE_SC_", "char const* (**std::__copy_backward<true, std::random_access_iterator_tag>::__copy_b<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>(char const* (* const*)(dyld_image_states, unsigned int, dyld_image_info const*), char const* (* const*)(dyld_image_states, unsigned int, dyld_image_info const*), char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*)))(dyld_image_states, unsigned int, dyld_image_info const*)"},
-    {"_ZNSt6vectorIPFPKc17dyld_image_statesjPK15dyld_image_infoESaIS7_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS7_S9_EERKS7_", "std::vector<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), std::allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>>::_M_insert_aux(__gnu_cxx::__normal_iterator<char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*), std::vector<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), std::allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>>>, char const* (* const&)(dyld_image_states, unsigned int, dyld_image_info const*))"},
-    {"_ZNSt6vectorIPFPKc17dyld_image_statesjPK15dyld_image_infoESaIS7_EE6insertEN9__gnu_cxx17__normal_iteratorIPS7_S9_EERKS7_", "std::vector<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), std::allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>>::insert(__gnu_cxx::__normal_iterator<char const* (**)(dyld_image_states, unsigned int, dyld_image_info const*), std::vector<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), std::allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>>>, char const* (* const&)(dyld_image_states, unsigned int, dyld_image_info const*))"},
-    {"_ZNSt6vectorIPFPKc17dyld_image_statesjPK15dyld_image_infoESaIS7_EE9push_backERKS7_", "std::vector<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), std::allocator<char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)>>::push_back(char const* (* const&)(dyld_image_states, unsigned int, dyld_image_info const*))"},
-    {"_ZNSt15__copy_backwardILb1ESt26random_access_iterator_tagE8__copy_bIPFvPK11mach_headerlEEEPT_PKS8_SB_S9_", "void (**std::__copy_backward<true, std::random_access_iterator_tag>::__copy_b<void (*)(mach_header const*, long)>(void (* const*)(mach_header const*, long), void (* const*)(mach_header const*, long), void (**)(mach_header const*, long)))(mach_header const*, long)"},
-    {"_ZNSt6vectorIPFvPK11mach_headerlESaIS4_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS4_S6_EERKS4_", "std::vector<void (*)(mach_header const*, long), std::allocator<void (*)(mach_header const*, long)>>::_M_insert_aux(__gnu_cxx::__normal_iterator<void (**)(mach_header const*, long), std::vector<void (*)(mach_header const*, long), std::allocator<void (*)(mach_header const*, long)>>>, void (* const&)(mach_header const*, long))"},
-    {"_ZNSt6vectorIPFvPK11mach_headerlESaIS4_EE9push_backERKS4_", "std::vector<void (*)(mach_header const*, long), std::allocator<void (*)(mach_header const*, long)>>::push_back(void (* const&)(mach_header const*, long))"},
-    {"_ZNSt15__copy_backwardILb1ESt26random_access_iterator_tagE8__copy_bIPKcEEPT_PKS5_S8_S6_", "char const** std::__copy_backward<true, std::random_access_iterator_tag>::__copy_b<char const*>(char const* const*, char const* const*, char const**)"},
-    {"_ZNSt6vectorIPKcSaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_", "std::vector<char const*, std::allocator<char const*>>::_M_insert_aux(__gnu_cxx::__normal_iterator<char const**, std::vector<char const*, std::allocator<char const*>>>, char const* const&)"},
-    {"_ZNSt6vectorIPKcSaIS1_EE9push_backERKS1_", "std::vector<char const*, std::allocator<char const*>>::push_back(char const* const&)"},
-    {"_ZNSt15__copy_backwardILb1ESt26random_access_iterator_tagE8__copy_bIP11ImageLoaderEEPT_PKS5_S8_S6_", "ImageLoader** std::__copy_backward<true, std::random_access_iterator_tag>::__copy_b<ImageLoader*>(ImageLoader* const*, ImageLoader* const*, ImageLoader**)"},
-    {"_ZNSt6vectorIPFvPK11mach_headerlESaIS4_EE20_M_allocate_and_copyIPS4_EES8_mT_S9_", "void (**std::vector<void (*)(mach_header const*, long), std::allocator<void (*)(mach_header const*, long)>>::_M_allocate_and_copy<void (**)(mach_header const*, long)>(unsigned long, void (**)(mach_header const*, long), void (**)(mach_header const*, long)))(mach_header const*, long)"},
-    {"_ZNSt6vectorIPFvPK11mach_headerlESaIS4_EE7reserveEm", "std::vector<void (*)(mach_header const*, long), std::allocator<void (*)(mach_header const*, long)>>::reserve(unsigned long)"},
-    {"_ZNSt6vectorIN4dyld13RegisteredDOFESaIS1_EE20_M_allocate_and_copyIPS1_EES5_mT_S6_", "dyld::RegisteredDOF* std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>::_M_allocate_and_copy<dyld::RegisteredDOF*>(unsigned long, dyld::RegisteredDOF*, dyld::RegisteredDOF*)"},
-    {"_ZNSt6vectorIN4dyld13RegisteredDOFESaIS1_EE7reserveEm", "std::vector<dyld::RegisteredDOF, std::allocator<dyld::RegisteredDOF>>::reserve(unsigned long)"},
-    {"_ZSt18uninitialized_copyIPP11ImageLoaderS2_ET0_T_S4_S3_", "ImageLoader** std::uninitialized_copy<ImageLoader**, ImageLoader**>(ImageLoader**, ImageLoader**, ImageLoader**)"},
-    {"_ZNSt6vectorIP11ImageLoaderSaIS1_EE20_M_allocate_and_copyIPS1_EES5_mT_S6_", "ImageLoader** std::vector<ImageLoader*, std::allocator<ImageLoader*>>::_M_allocate_and_copy<ImageLoader**>(unsigned long, ImageLoader**, ImageLoader**)"},
-    {"_ZNSt6vectorIP11ImageLoaderSaIS1_EE7reserveEm", "std::vector<ImageLoader*, std::allocator<ImageLoader*>>::reserve(unsigned long)"},
-    {"_ZNSt6vectorIP11ImageLoaderSaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_", "std::vector<ImageLoader*, std::allocator<ImageLoader*>>::_M_insert_aux(__gnu_cxx::__normal_iterator<ImageLoader**, std::vector<ImageLoader*, std::allocator<ImageLoader*>>>, ImageLoader* const&)"},
-    {"_ZNSt6vectorIP11ImageLoaderSaIS1_EE9push_backERKS1_", "std::vector<ImageLoader*, std::allocator<ImageLoader*>>::push_back(ImageLoader* const&)"},
-    {"_ZNSt6vectorIP11ImageLoaderSaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE", "std::vector<ImageLoader*, std::allocator<ImageLoader*>>::erase(__gnu_cxx::__normal_iterator<ImageLoader**, std::vector<ImageLoader*, std::allocator<ImageLoader*>>>)"},
-    {"_Z18lookupDyldFunctionPKcPm", "lookupDyldFunction(char const*, unsigned long*)"},
-    {"_ZNSt12_Vector_baseIP19__NSObjectFileImageSaIS1_EED2Ev", "std::_Vector_base<__NSObjectFileImage*, std::allocator<__NSObjectFileImage*>>::~_Vector_base()"},
-    {"_ZNSt6vectorIP19__NSObjectFileImageSaIS1_EED2Ev", "std::vector<__NSObjectFileImage*, std::allocator<__NSObjectFileImage*>>::~vector()"},
-    {"_ZNSt15__copy_backwardILb1ESt26random_access_iterator_tagE8__copy_bIP19__NSObjectFileImageEEPT_PKS5_S8_S6_", "__NSObjectFileImage** std::__copy_backward<true, std::random_access_iterator_tag>::__copy_b<__NSObjectFileImage*>(__NSObjectFileImage* const*, __NSObjectFileImage* const*, __NSObjectFileImage**)"},
-    {"_ZN9__gnu_cxx13new_allocatorIP19__NSObjectFileImageE8allocateEmPKv", "__gnu_cxx::new_allocator<__NSObjectFileImage*>::allocate(unsigned long, void const*)"},
-    {"_ZNSt6vectorIP19__NSObjectFileImageSaIS1_EE13_M_insert_auxEN9__gnu_cxx17__normal_iteratorIPS1_S3_EERKS1_", "std::vector<__NSObjectFileImage*, std::allocator<__NSObjectFileImage*>>::_M_insert_aux(__gnu_cxx::__normal_iterator<__NSObjectFileImage**, std::vector<__NSObjectFileImage*, std::allocator<__NSObjectFileImage*>>>, __NSObjectFileImage* const&)"},
-    {"_ZNSt6vectorIP19__NSObjectFileImageSaIS1_EE9push_backERKS1_", "std::vector<__NSObjectFileImage*, std::allocator<__NSObjectFileImage*>>::push_back(__NSObjectFileImage* const&)"},
-    {"_ZNSt6vectorIP19__NSObjectFileImageSaIS1_EE5eraseEN9__gnu_cxx17__normal_iteratorIPS1_S3_EE", "std::vector<__NSObjectFileImage*, std::allocator<__NSObjectFileImage*>>::erase(__gnu_cxx::__normal_iterator<__NSObjectFileImage**, std::vector<__NSObjectFileImage*, std::allocator<__NSObjectFileImage*>>>)"},
-    {"_Z19setAlImageInfosHaltPKcm", "setAlImageInfosHalt(char const*, unsigned long)"},
-    {"_Z24removeImageFromAllImagesPK11mach_header", "removeImageFromAllImages(mach_header const*)"},
-    {"_Z20addImagesToAllImagesjPK15dyld_image_info", "addImagesToAllImages(unsigned int, dyld_image_info const*)"},
-    {"...
[truncated]

Copy link

github-actions bot commented Apr 30, 2025

⚠️ undef deprecator found issues in your code. ⚠️

You can test this locally with the following command:
git diff -U0 --pickaxe-regex -S '([^a-zA-Z0-9#_-]undef[^a-zA-Z0-9_-]|UndefValue::get)' 'HEAD~1' HEAD libcxxabi/test/DemangleTestCases.inc llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc libcxxabi/test/test_demangle.pass.cpp

The following files introduce new uses of undef:

  • libcxxabi/test/DemangleTestCases.inc
  • llvm/include/llvm/Testing/Demangle/DemangleTestCases.inc

Undef is now deprecated and should only be used in the rare cases where no replacement is possible. For example, a load of uninitialized memory yields undef. You should use poison values for placeholders instead.

In tests, avoid using undef and having tests that trigger undefined behavior. If you need an operand with some unimportant value, you can add a new argument to the function and use that instead.

For example, this is considered a bad practice:

define void @fn() {
  ...
  br i1 undef, ...
}

Please use the following instead:

define void @fn(i1 %cond) {
  ...
  br i1 %cond, ...
}

Please refer to the Undefined Behavior Manual for more information.

@Michael137 Michael137 requested a review from urnathan April 30, 2025 17:34
@Michael137
Copy link
Member Author

Weirdly on the Windows PR CI I'm getting:

C:\ws\src\llvm\unittests\Demangle\ItaniumDemangleTest.cpp:291
Value of: expected
Expected: contains at least one element that is equal to "void test0::g<float>(char (&) [sizeof ((float)() + 0x1.4000000000000p+2f)])"
  Actual: { "void test0::g<float>(char (&) [sizeof ((float)() + 0x1.4p+2f)])", "void test0::g<float>(char (&) [sizeof ((float)() + 0x2.8p+1f)])", "void test0::g<float>(char (&) [sizeof ((float)() + 0x5p+0f)])", "void test0::g<float>(char (&) [sizeof ((float)() + 0xap-1f)])" }

And on Linux:

/var/lib/buildkite-agent/builds/linux-56-59b8f5d88-qrmz7-1/llvm-project/github-pull-requests/llvm/unittests/Demangle/ItaniumDemangleTest.cpp:224
Expected equality of these values:
  nullptr
    Which is: NULL
  Root
    Which is: 0x59ea97f46ba0
Unexpectedly succeeded demangling: _ZN5test01hIfEEvRAcvjplstT_Le4001a000000000000000E_c

Not sure what's special about these bot configurations and why the libcxx bots weren't failing with these. @mstorsjo any ideas? I see you ran into something similar in #134976

@mstorsjo
Copy link
Member

mstorsjo commented May 2, 2025

I have a couple of things to point out, which I think can explain most of these:

  • The demangler, when operating in libcxxabi, only expects to be able to demangle strings from the current build configuration, hence the ifdefs for current architecture wrt long double and such. This is in quite in contrast to LLVM in general, where any build of LLVM expects to be able to deal with data from any target architecture. (I'm not sure how this is meant to work with the demangler in particular though - this is a preexisting issue.)

  • Within libcxxabi, the demangler has only been tested in mingw build configurations, not in msvc build configurations, as the libcxxabi library isn't relevant (or even possible to compile) in MSVC mode. (Mingw configurations do have x87 80 bit long doubles on both i386 and x86_64, contrary to msvc build configurations that has 64 bit long doubles.) The windows buildbots build in msvc mode. (The libcxx CI does have mingw configurations though, and this testcase has been run in that configuration before.)

  • The linux test failure probably is explained by the fact that the test currently uses #if !LDBL_FP80 before the actual definition of LDBL_FP80 further down in the file

  • You seem to be on track with the Windows test failure (with the recently pushed amendment). With the Microsoft CRT, printf("%a") formats hex floats differently than most other C runtimes. This is the reason for the XFAIL: win32-broken-printf-a-precision in the current libcxxabi/test/test_demangle.pass.cpp - see ca69f51 for details about this. If those bits of the tests are removed from libcxxabi/test/test_demangle.pass.cpp, we probably should remove that XFAIL from there as well. (I can try to run a test configuration with that case on your PR when it is nearing completion to check this; this isn't covered in upstream CI.)

  • The code in libcxxabi used to expect to only be built with GCC compatible compilers, while the code in LLVM also can be built by regular MSVC. So the testcase code directly uses __LDBL_MANT_DIG__ right now, while GCC and Clang do define (even in MSVC mode), but regular MSVC itself doesn't define that. That's why the implementation had to include a || defined(_MSC_VER) case in 3b70715. When moved to LLVM, the testcase will also need to work when built with regular MSVC. But it may very well be the case that the existing #define LDBL_FP80 (__LDBL_MANT_DIG__ == 64) will just end up doing the right thing anyway, as MSVC has got 64 bit long doubles (i.e. __LDBL_MANT_DIG__ == 53).

@Michael137
Copy link
Member Author

Michael137 commented May 2, 2025

Thanks for all the context!

The linux test failure probably is explained by the fact that the test currently uses #if !LDBL_FP80 before the actual definition of LDBL_FP80 further down in the file

Hah good catch!

we probably should remove that XFAIL from there as well. (I can try to run a test configuration with that case on your PR when it is nearing completion to check this; this isn't covered in upstream CI.)

Just pushed a commit that removes that XFAIL, if you want to give it a shot. Thank you!

@mstorsjo
Copy link
Member

mstorsjo commented May 2, 2025

we probably should remove that XFAIL from there as well. (I can try to run a test configuration with that case on your PR when it is nearing completion to check this; this isn't covered in upstream CI.)

Just pushed a commit that removes that XFAIL, if you want to give it a shot. Thank you!

This form of the PR does seem to work fine in a configuration with win32-broken-printf-a-precision, so this should be all fine with respect to that now. Thanks!

Copy link
Member

@ldionne ldionne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it makes sense to remove this test coverage from libc++abi, since it really weakens the tests for libc++abi. Instead, would it make sense to do what you're doing here and store the test cases in a text file, and then load that from both the LLVM tests and from the libc++abi tests? That way both can keep the full coverage yet there is a single source of truth for these test cases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be a leftover #if 0 in this file (you can't see it on the diff here but you can click "view file").

@Michael137
Copy link
Member Author

I don't think it makes sense to remove this test coverage from libc++abi, since it really weakens the tests for libc++abi. Instead, would it make sense to do what you're doing here and store the test cases in a text file, and then load that from both the LLVM tests and from the libc++abi tests? That way both can keep the full coverage yet there is a single source of truth for these test cases.

Yea that should work. Are you suggesting we put the test-cases in libcxxabi/test/ next to test_demangle.pass.cpp and then adjust the cp-to-llvm.sh script to sync that file into the LLVM repo? Or should this file be distributed like other headers and LLVM would just reach into libcxxabi to include this file? From LLDB's perspective I would prefer the former, because libcxxabi isn't always a requirement to run the LLDB tests. So if we could have the file synced into LLVM that would work for us.

Also, if we have the tests in both test_demangle.pass.cpp and LLVM, what should we do with the test-cases that test invalid inputs and floating point inputs. Those are currently separate test-cases in test_demangle.pass.cpp. Should we keep them in one place only? Or also factor out the test-cases into separate files and have tests for them in libc++abi and LLVM?

@ldionne
Copy link
Member

ldionne commented May 6, 2025

Yea that should work. Are you suggesting we put the test-cases in libcxxabi/test/ next to test_demangle.pass.cpp and then adjust the cp-to-llvm.sh script to sync that file into the LLVM repo? Or should this file be distributed like other headers and LLVM would just reach into libcxxabi to include this file? From LLDB's perspective I would prefer the former, because libcxxabi isn't always a requirement to run the LLDB tests. So if we could have the file synced into LLVM that would work for us.

I'm neutral on this, both solutions would satisfy me. I don't know the constraints of LLDB and testing the LLVM variant of this code, so I can't weigh in on that.

Also, if we have the tests in both test_demangle.pass.cpp and LLVM, what should we do with the test-cases that test invalid inputs and floating point inputs. Those are currently separate test-cases in test_demangle.pass.cpp. Should we keep them in one place only? Or also factor out the test-cases into separate files and have tests for them in libc++abi and LLVM?

In an ideal world, I think that if there's an easy way to also hoist these test cases into something that can be shared, then we would achieve maximal coverage and maximal reuse. But that might not be easy to do and it might not be worth it if doing so introduces a lot of complexity. On my end, I'd simply ask that we don't decrease the existing coverage in libc++abi.

@Michael137
Copy link
Member Author

Michael137 commented May 6, 2025

Since the main goal of all of this is to just get some additional testing into LLDB, maybe all we should do is put those test-cases in a text-file, sync it into LLVM, and make it accessible to LLDB that way? Without adding/copying the tests into LLVM? That avoids having the test-code in 2 places. The weird part is having this text-file live in LLVM and only be used from LLDB tests. But maybe that's fine.

Copy link

github-actions bot commented May 6, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@Michael137 Michael137 force-pushed the llvm/move-demangler-tests branch from ff2f7c0 to a7abc68 Compare May 6, 2025 22:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++abi libc++abi C++ Runtime Library. Not libc++.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants