├── .arcconfig ├── .clang-format ├── .gitignore ├── CMakeLists.txt ├── COPYING ├── CREDITS.TXT ├── LICENSE.TXT ├── README.md ├── cmake ├── Modules │ ├── HandleCompilerRT.cmake │ ├── HandleLibcxxabiFlags.cmake │ ├── HandleOutOfTreeLLVM.cmake │ └── MacroEnsureOutOfSourceBuild.cmake └── config-ix.cmake ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── rules └── source │ └── format ├── fuzz ├── CMakeLists.txt └── cxa_demangle_fuzzer.cpp ├── include ├── __cxxabi_config.h └── cxxabi.h ├── lib └── buildit ├── rpmbuild ├── .gitignore └── SPECS │ └── cheerp-libcxxabi.spec ├── src ├── CMakeLists.txt ├── abort_message.cpp ├── abort_message.h ├── cxa_aux_runtime.cpp ├── cxa_default_handlers.cpp ├── cxa_demangle.cpp ├── cxa_exception.cpp ├── cxa_exception.hpp ├── cxa_exception_storage.cpp ├── cxa_guard.cpp ├── cxa_handlers.cpp ├── cxa_handlers.hpp ├── cxa_noexception.cpp ├── cxa_personality.cpp ├── cxa_thread_atexit.cpp ├── cxa_unexpected.cpp ├── cxa_vector.cpp ├── cxa_virtual.cpp ├── demangle │ ├── .clang-format │ ├── DemangleConfig.h │ ├── ItaniumDemangle.h │ ├── README.txt │ ├── StringView.h │ ├── Utility.h │ └── cp-to-llvm.sh ├── fallback_malloc.cpp ├── fallback_malloc.h ├── include │ ├── atomic_support.h │ └── refstring.h ├── private_typeinfo.cpp ├── private_typeinfo.h ├── stdlib_exception.cpp ├── stdlib_new_delete.cpp ├── stdlib_stdexcept.cpp └── stdlib_typeinfo.cpp ├── test ├── CMakeLists.txt ├── backtrace_test.pass.cpp ├── catch_array_01.pass.cpp ├── catch_array_02.pass.cpp ├── catch_class_01.pass.cpp ├── catch_class_02.pass.cpp ├── catch_class_03.pass.cpp ├── catch_class_04.pass.cpp ├── catch_const_pointer_nullptr.pass.cpp ├── catch_function_01.pass.cpp ├── catch_function_02.pass.cpp ├── catch_function_03.pass.cpp ├── catch_in_noexcept.pass.cpp ├── catch_member_data_pointer_01.pass.cpp ├── catch_member_function_pointer_01.pass.cpp ├── catch_member_function_pointer_02.pass.cpp ├── catch_member_pointer_nullptr.pass.cpp ├── catch_multi_level_pointer.pass.cpp ├── catch_pointer_nullptr.pass.cpp ├── catch_pointer_reference.pass.cpp ├── catch_ptr.pass.cpp ├── catch_ptr_02.pass.cpp ├── catch_reference_nullptr.pass.cpp ├── cxa_bad_cast.pass.cpp ├── cxa_bad_typeid.pass.cpp ├── cxa_thread_atexit_test.pass.cpp ├── dynamic_cast.pass.cpp ├── dynamic_cast14.pass.cpp ├── dynamic_cast3.pass.cpp ├── dynamic_cast5.pass.cpp ├── dynamic_cast_stress.pass.cpp ├── exception_object_alignment.pass.cpp ├── incomplete_type.sh.cpp ├── inherited_exception.pass.cpp ├── libcxxabi │ ├── __init__.py │ └── test │ │ ├── __init__.py │ │ └── config.py ├── lit.cfg ├── lit.site.cfg.in ├── native │ └── arm-linux-eabi │ │ ├── lit.local.cfg │ │ ├── ttype-encoding-00.pass.sh.s │ │ └── ttype-encoding-90.pass.sh.s ├── noexception1.pass.cpp ├── noexception2.pass.cpp ├── noexception3.pass.cpp ├── noexception4.pass.cpp ├── support │ └── timer.hpp ├── test_aux_runtime.pass.cpp ├── test_aux_runtime_op_array_new.pass.cpp ├── test_demangle.pass.cpp ├── test_exception_address_alignment.pass.cpp ├── test_exception_storage.pass.cpp ├── test_fallback_malloc.pass.cpp ├── test_guard.pass.cpp ├── test_vector1.pass.cpp ├── test_vector2.pass.cpp ├── test_vector3.pass.cpp ├── testit ├── thread_local_destruction_order.pass.cpp ├── uncaught_exceptions.pass.cpp ├── unittest_demangle.pass.cpp ├── unwind_01.pass.cpp ├── unwind_02.pass.cpp ├── unwind_03.pass.cpp ├── unwind_04.pass.cpp ├── unwind_05.pass.cpp └── unwind_06.pass.cpp └── www ├── content.css ├── index.html ├── menu.css └── spec.html /.arcconfig: -------------------------------------------------------------------------------- 1 | { 2 | "repository.callsign" : "CXXA", 3 | "conduit_uri" : "https://reviews.llvm.org/" 4 | } 5 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | 3 | --- 4 | Language: Cpp 5 | 6 | AlwaysBreakTemplateDeclarations: true 7 | PointerAlignment: Left 8 | 9 | # Disable formatting options which may break tests. 10 | SortIncludes: false 11 | ReflowComments: false 12 | --- 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # vim swap files 6 | .*.sw? 7 | .sw? 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | env/ 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | #lib/ # We actually have things checked in to lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | 47 | # Translations 48 | *.mo 49 | *.pot 50 | 51 | # Django stuff: 52 | *.log 53 | 54 | # Sphinx documentation 55 | docs/_build/ 56 | 57 | # PyBuilder 58 | target/ 59 | -------------------------------------------------------------------------------- /CREDITS.TXT: -------------------------------------------------------------------------------- 1 | This file is a partial list of people who have contributed to the LLVM/libc++abi 2 | project. If you have contributed a patch or made some other contribution to 3 | LLVM/libc++abi, please submit a patch to this file to add yourself, and it will be 4 | done! 5 | 6 | The list is sorted by surname and formatted to allow easy grepping and 7 | beautification by scripts. The fields are: name (N), email (E), web-address 8 | (W), PGP key ID and fingerprint (P), description (D), and snail-mail address 9 | (S). 10 | 11 | N: Aaron Ballman 12 | E: aaron@aaronballman.com 13 | D: Minor patches 14 | 15 | N: Logan Chien 16 | E: logan.chien@mediatek.com 17 | D: ARM EHABI Unwind & Exception Handling 18 | 19 | N: Marshall Clow 20 | E: mclow.lists@gmail.com 21 | E: marshall@idio.com 22 | D: Architect and primary coauthor of libc++abi 23 | 24 | N: Matthew Dempsky 25 | E: matthew@dempsky.org 26 | D: Minor patches and bug fixes. 27 | 28 | N: Nowar Gu 29 | E: wenhan.gu@gmail.com 30 | D: Minor patches and fixes 31 | 32 | N: Howard Hinnant 33 | E: hhinnant@apple.com 34 | D: Architect and primary coauthor of libc++abi 35 | 36 | N: Dana Jansens 37 | E: danakj@chromium.org 38 | D: ARM EHABI Unwind & Exception Handling 39 | 40 | N: Nick Kledzik 41 | E: kledzik@apple.com 42 | 43 | N: Antoine Labour 44 | E: piman@chromium.org 45 | D: ARM EHABI Unwind & Exception Handling 46 | 47 | N: Bruce Mitchener, Jr. 48 | E: bruce.mitchener@gmail.com 49 | D: Minor typo fixes 50 | 51 | N: Andrew Morrow 52 | E: andrew.c.morrow@gmail.com 53 | D: Minor patches and fixes 54 | 55 | N: Erik Olofsson 56 | E: erik.olofsson@hansoft.se 57 | E: erik@olofsson.info 58 | D: Minor patches and fixes 59 | 60 | N: Jon Roelofs 61 | E: jroelofs@jroelofs.com 62 | D: ARM EHABI Unwind & Exception Handling, Bare-metal 63 | 64 | N: Nico Weber 65 | E: thakis@chromium.org 66 | D: ARM EHABI Unwind & Exception Handling 67 | 68 | N: Albert J. Wong 69 | E: ajwong@google.com 70 | D: ARM EHABI Unwind & Exception Handling 71 | 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Cheerp: A C++ compiler for the Web 2 | ================================== 3 | 4 | This repo is outdated. Please refer to https://github.com/leaningtech/cheerp-compiler to build libcxxabi. 5 | 6 | Please report bugs on launchpad: 7 | https://bugs.launchpad.net/cheerp 8 | 9 | Cheerp libcxxabi build instructions 10 | ----------------------------------- 11 | 12 | Building the cheerp-enabled libcxx (C++ standard library) requires having the cheerp 13 | compiler already installed in /opt/cheerp. It also require libcxx-cheerp headers. 14 | 15 | ``` 16 | git clone libcxx 17 | mkdir build 18 | cd build 19 | cmake -DCMAKE_INSTALL_PREFIX=/opt/cheerp -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/opt/cheerp/share/cmake/Modules/CheerpToolchain.cmake -DCHEERP_LINEAR_OUTPUT=asmjs -DLIBCXXABI_ENABLE_SHARED=OFF -DLIBCXXABI_ENABLE_ASSERTIONS=OFF -DLIBCXXABI_LIBCXX_PATH=$PWD/../libcxx/ -DLIBCXXABI_LIBCXX_INCLUDES=$PWD/../libcxx/include -DLIBCXXABI_ENABLE_THREADS=0 -DLLVM_CONFIG=/opt/cheerp/bin/llvm-config .. 20 | make 21 | make install 22 | ``` 23 | 24 | Cheerp libcxxabi build instructions (asm.js version) 25 | ------------------------------------------------- 26 | 27 | It is recommended to create another build directory: 28 | 29 | ``` 30 | mkdir build_asmjs 31 | cd build_asmjs 32 | ``` 33 | 34 | The rest of the instructions are the same, except for the cmake toolchain file, 35 | which is `CheerpWasmToolchain.cmake`: 36 | 37 | ``` 38 | cmake -DCMAKE_INSTALL_PREFIX=/opt/cheerp -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/opt/cheerp/share/cmake/Modules/CheerpWasmToolchain.cmake -DCHEERP_LINEAR_OUTPUT=asmjs -DLIBCXXABI_ENABLE_SHARED=OFF -DLIBCXXABI_ENABLE_ASSERTIONS=OFF -DLIBCXXABI_LIBCXX_PATH=$PWD/../libcxx/ -DLIBCXXABI_LIBCXX_INCLUDES=$PWD/../libcxx/include -DLIBCXXABI_ENABLE_THREADS=0 -DLLVM_CONFIG=/opt/cheerp/bin/llvm-config .. 39 | make 40 | make install 41 | ``` 42 | -------------------------------------------------------------------------------- /cmake/Modules/HandleCompilerRT.cmake: -------------------------------------------------------------------------------- 1 | function(find_compiler_rt_library name dest) 2 | if (NOT DEFINED LIBCXXABI_COMPILE_FLAGS) 3 | message(FATAL_ERROR "LIBCXXABI_COMPILE_FLAGS must be defined when using this function") 4 | endif() 5 | set(dest "" PARENT_SCOPE) 6 | set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXXABI_COMPILE_FLAGS} 7 | "--rtlib=compiler-rt" "--print-libgcc-file-name") 8 | if (CMAKE_CXX_COMPILER_ID MATCHES Clang AND CMAKE_CXX_COMPILER_TARGET) 9 | list(APPEND CLANG_COMMAND "--target=${CMAKE_CXX_COMPILER_TARGET}") 10 | endif() 11 | get_property(LIBCXXABI_CXX_FLAGS CACHE CMAKE_CXX_FLAGS PROPERTY VALUE) 12 | string(REPLACE " " ";" LIBCXXABI_CXX_FLAGS "${LIBCXXABI_CXX_FLAGS}") 13 | list(APPEND CLANG_COMMAND ${LIBCXXABI_CXX_FLAGS}) 14 | execute_process( 15 | COMMAND ${CLANG_COMMAND} 16 | RESULT_VARIABLE HAD_ERROR 17 | OUTPUT_VARIABLE LIBRARY_FILE 18 | ) 19 | string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE) 20 | file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE) 21 | string(REPLACE "builtins" "${name}" LIBRARY_FILE "${LIBRARY_FILE}") 22 | if (NOT HAD_ERROR AND EXISTS "${LIBRARY_FILE}") 23 | message(STATUS "Found compiler-rt library: ${LIBRARY_FILE}") 24 | set(${dest} "${LIBRARY_FILE}" PARENT_SCOPE) 25 | else() 26 | message(STATUS "Failed to find compiler-rt library") 27 | endif() 28 | endfunction() 29 | 30 | function(find_compiler_rt_dir dest) 31 | if (NOT DEFINED LIBCXXABI_COMPILE_FLAGS) 32 | message(FATAL_ERROR "LIBCXXABI_COMPILE_FLAGS must be defined when using this function") 33 | endif() 34 | set(dest "" PARENT_SCOPE) 35 | if (APPLE) 36 | set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXXABI_COMPILE_FLAGS} 37 | "-print-file-name=lib") 38 | execute_process( 39 | COMMAND ${CLANG_COMMAND} 40 | RESULT_VARIABLE HAD_ERROR 41 | OUTPUT_VARIABLE LIBRARY_DIR 42 | ) 43 | string(STRIP "${LIBRARY_DIR}" LIBRARY_DIR) 44 | file(TO_CMAKE_PATH "${LIBRARY_DIR}" LIBRARY_DIR) 45 | set(LIBRARY_DIR "${LIBRARY_DIR}/darwin") 46 | else() 47 | set(CLANG_COMMAND ${CMAKE_CXX_COMPILER} ${LIBCXXABI_COMPILE_FLAGS} 48 | "--rtlib=compiler-rt" "--print-libgcc-file-name") 49 | execute_process( 50 | COMMAND ${CLANG_COMMAND} 51 | RESULT_VARIABLE HAD_ERROR 52 | OUTPUT_VARIABLE LIBRARY_FILE 53 | ) 54 | string(STRIP "${LIBRARY_FILE}" LIBRARY_FILE) 55 | file(TO_CMAKE_PATH "${LIBRARY_FILE}" LIBRARY_FILE) 56 | get_filename_component(LIBRARY_DIR "${LIBRARY_FILE}" DIRECTORY) 57 | endif() 58 | if (NOT HAD_ERROR AND EXISTS "${LIBRARY_DIR}") 59 | message(STATUS "Found compiler-rt directory: ${LIBRARY_DIR}") 60 | set(${dest} "${LIBRARY_DIR}" PARENT_SCOPE) 61 | else() 62 | message(STATUS "Failed to find compiler-rt directory") 63 | endif() 64 | endfunction() 65 | -------------------------------------------------------------------------------- /cmake/Modules/HandleOutOfTreeLLVM.cmake: -------------------------------------------------------------------------------- 1 | macro(find_llvm_parts) 2 | # Rely on llvm-config. 3 | set(CONFIG_OUTPUT) 4 | if(NOT LLVM_CONFIG_PATH) 5 | find_program(LLVM_CONFIG_PATH "llvm-config") 6 | endif() 7 | if(DEFINED LLVM_PATH) 8 | set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include") 9 | set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree") 10 | set(LLVM_MAIN_SRC_DIR ${LLVM_PATH}) 11 | set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules") 12 | elseif(LLVM_CONFIG_PATH) 13 | message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}") 14 | set(LIBCXXABI_USING_INSTALLED_LLVM 1) 15 | set(CONFIG_COMMAND ${LLVM_CONFIG_PATH} 16 | "--includedir" 17 | "--prefix" 18 | "--src-root") 19 | execute_process( 20 | COMMAND ${CONFIG_COMMAND} 21 | RESULT_VARIABLE HAD_ERROR 22 | OUTPUT_VARIABLE CONFIG_OUTPUT 23 | ) 24 | if(NOT HAD_ERROR) 25 | string(REGEX REPLACE 26 | "[ \t]*[\r\n]+[ \t]*" ";" 27 | CONFIG_OUTPUT ${CONFIG_OUTPUT}) 28 | else() 29 | string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") 30 | message(STATUS "${CONFIG_COMMAND_STR}") 31 | message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") 32 | endif() 33 | 34 | list(GET CONFIG_OUTPUT 0 INCLUDE_DIR) 35 | list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT) 36 | list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR) 37 | 38 | set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") 39 | set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") 40 | set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") 41 | 42 | # --cmakedir is supported since llvm r291218 (4.0 release) 43 | execute_process( 44 | COMMAND ${LLVM_CONFIG_PATH} --cmakedir 45 | RESULT_VARIABLE HAD_ERROR 46 | OUTPUT_VARIABLE CONFIG_OUTPUT 47 | ERROR_QUIET) 48 | if(NOT HAD_ERROR) 49 | string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH_FROM_LLVM_CONFIG) 50 | file(TO_CMAKE_PATH "${LLVM_CMAKE_PATH_FROM_LLVM_CONFIG}" LLVM_CMAKE_PATH) 51 | else() 52 | file(TO_CMAKE_PATH "${LLVM_BINARY_DIR}" LLVM_BINARY_DIR_CMAKE_STYLE) 53 | set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") 54 | endif() 55 | else() 56 | set(LLVM_FOUND OFF) 57 | message(WARNING "UNSUPPORTED LIBCXXABI CONFIGURATION DETECTED: " 58 | "llvm-config not found and LLVM_PATH not defined.\n" 59 | "Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config " 60 | "or -DLLVM_PATH=path/to/llvm-source-root.") 61 | return() 62 | endif() 63 | 64 | if (EXISTS "${LLVM_CMAKE_PATH}") 65 | list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") 66 | elseif (EXISTS "${LLVM_MAIN_SRC_DIR}/cmake/modules") 67 | list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") 68 | else() 69 | set(LLVM_FOUND OFF) 70 | message(WARNING "Neither ${LLVM_CMAKE_PATH} nor ${LLVM_MAIN_SRC_DIR}/cmake/modules found") 71 | return() 72 | endif() 73 | 74 | set(LLVM_FOUND ON) 75 | endmacro(find_llvm_parts) 76 | 77 | macro(configure_out_of_tree_llvm) 78 | message(STATUS "Configuring for standalone build.") 79 | set(LIBCXXABI_STANDALONE_BUILD 1) 80 | 81 | find_llvm_parts() 82 | 83 | # Add LLVM Functions -------------------------------------------------------- 84 | if (LLVM_FOUND AND LIBCXXABI_USING_INSTALLED_LLVM) 85 | include(LLVMConfig) # For TARGET_TRIPLE 86 | else() 87 | if (WIN32) 88 | set(LLVM_ON_UNIX 0) 89 | set(LLVM_ON_WIN32 1) 90 | else() 91 | set(LLVM_ON_UNIX 1) 92 | set(LLVM_ON_WIN32 0) 93 | endif() 94 | endif() 95 | if (LLVM_FOUND) 96 | # Enable warnings, otherwise -w gets added to the cflags by HandleLLVMOptions. 97 | set(LLVM_ENABLE_WARNINGS ON) 98 | include(AddLLVM OPTIONAL) 99 | include(HandleLLVMOptions OPTIONAL) 100 | endif() 101 | 102 | # LLVM Options -------------------------------------------------------------- 103 | if (NOT DEFINED LLVM_INCLUDE_TESTS) 104 | set(LLVM_INCLUDE_TESTS ${LLVM_FOUND}) 105 | endif() 106 | if (NOT DEFINED LLVM_INCLUDE_DOCS) 107 | set(LLVM_INCLUDE_DOCS ${LLVM_FOUND}) 108 | endif() 109 | if (NOT DEFINED LLVM_ENABLE_SPHINX) 110 | set(LLVM_ENABLE_SPHINX OFF) 111 | endif() 112 | 113 | # In a standalone build, we don't have llvm to automatically generate the 114 | # llvm-lit script for us. So we need to provide an explicit directory that 115 | # the configurator should write the script into. 116 | set(LLVM_LIT_OUTPUT_DIR "${libcxxabi_BINARY_DIR}/bin") 117 | 118 | if (LLVM_INCLUDE_TESTS) 119 | # Required LIT Configuration ------------------------------------------------ 120 | # Define the default arguments to use with 'lit', and an option for the user 121 | # to override. 122 | set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py") 123 | set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported") 124 | if (MSVC OR XCODE) 125 | set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") 126 | endif() 127 | set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") 128 | endif() 129 | 130 | # Required doc configuration 131 | if (LLVM_ENABLE_SPHINX) 132 | find_package(Sphinx REQUIRED) 133 | endif() 134 | 135 | if (LLVM_ON_UNIX AND NOT APPLE) 136 | set(LLVM_HAVE_LINK_VERSION_SCRIPT 1) 137 | else() 138 | set(LLVM_HAVE_LINK_VERSION_SCRIPT 0) 139 | endif() 140 | endmacro(configure_out_of_tree_llvm) 141 | 142 | configure_out_of_tree_llvm() 143 | -------------------------------------------------------------------------------- /cmake/Modules/MacroEnsureOutOfSourceBuild.cmake: -------------------------------------------------------------------------------- 1 | # MACRO_ENSURE_OUT_OF_SOURCE_BUILD() 2 | 3 | macro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage ) 4 | 5 | string( COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource ) 6 | if( _insource ) 7 | message( SEND_ERROR "${_errorMessage}" ) 8 | message( FATAL_ERROR 9 | "In-source builds are not allowed. 10 | CMake would overwrite the makefiles distributed with libcxxabi. 11 | Please create a directory and run cmake from there, passing the path 12 | to this source directory as the last argument. 13 | This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. 14 | Please delete them." 15 | ) 16 | endif( _insource ) 17 | 18 | endmacro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD ) 19 | -------------------------------------------------------------------------------- /cmake/config-ix.cmake: -------------------------------------------------------------------------------- 1 | include(CheckLibraryExists) 2 | include(CheckCCompilerFlag) 3 | include(CheckCXXCompilerFlag) 4 | 5 | check_library_exists(c fopen "" LIBCXXABI_HAS_C_LIB) 6 | if (NOT LIBCXXABI_USE_COMPILER_RT) 7 | check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXXABI_HAS_GCC_S_LIB) 8 | endif () 9 | 10 | # libc++abi is built with -nodefaultlibs, so we want all our checks to also 11 | # use this option, otherwise we may end up with an inconsistency between 12 | # the flags we think we require during configuration (if the checks are 13 | # performed without -nodefaultlibs) and the flags that are actually 14 | # required during compilation (which has the -nodefaultlibs). libc is 15 | # required for the link to go through. We remove sanitizers from the 16 | # configuration checks to avoid spurious link errors. 17 | check_c_compiler_flag(-nodefaultlibs LIBCXXABI_HAS_NODEFAULTLIBS_FLAG) 18 | if (LIBCXXABI_HAS_NODEFAULTLIBS_FLAG) 19 | set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs") 20 | if (LIBCXXABI_HAS_C_LIB) 21 | list(APPEND CMAKE_REQUIRED_LIBRARIES c) 22 | endif () 23 | if (LIBCXXABI_USE_COMPILER_RT) 24 | list(APPEND CMAKE_REQUIRED_FLAGS -rtlib=compiler-rt) 25 | find_compiler_rt_library(builtins LIBCXXABI_BUILTINS_LIBRARY) 26 | list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXXABI_BUILTINS_LIBRARY}") 27 | elseif (LIBCXXABI_HAS_GCC_S_LIB) 28 | list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s) 29 | endif () 30 | if (MINGW) 31 | # Mingw64 requires quite a few "C" runtime libraries in order for basic 32 | # programs to link successfully with -nodefaultlibs. 33 | if (LIBCXXABI_USE_COMPILER_RT) 34 | set(MINGW_RUNTIME ${LIBCXXABI_BUILTINS_LIBRARY}) 35 | else () 36 | set(MINGW_RUNTIME gcc_s gcc) 37 | endif() 38 | set(MINGW_LIBRARIES mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt advapi32 39 | shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME} 40 | moldname mingwex msvcrt) 41 | list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES}) 42 | endif() 43 | if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize) 44 | set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all") 45 | endif () 46 | if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage) 47 | set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters") 48 | endif () 49 | endif () 50 | 51 | # Check compiler flags 52 | check_c_compiler_flag(-funwind-tables LIBCXXABI_HAS_FUNWIND_TABLES) 53 | check_cxx_compiler_flag(-fno-exceptions LIBCXXABI_HAS_NO_EXCEPTIONS_FLAG) 54 | check_cxx_compiler_flag(-fno-rtti LIBCXXABI_HAS_NO_RTTI_FLAG) 55 | check_cxx_compiler_flag(-fstrict-aliasing LIBCXXABI_HAS_FSTRICT_ALIASING_FLAG) 56 | check_cxx_compiler_flag(-nostdinc++ LIBCXXABI_HAS_NOSTDINCXX_FLAG) 57 | check_cxx_compiler_flag(-Wall LIBCXXABI_HAS_WALL_FLAG) 58 | check_cxx_compiler_flag(-W LIBCXXABI_HAS_W_FLAG) 59 | check_cxx_compiler_flag(-Wunused-function LIBCXXABI_HAS_WUNUSED_FUNCTION_FLAG) 60 | check_cxx_compiler_flag(-Wunused-variable LIBCXXABI_HAS_WUNUSED_VARIABLE_FLAG) 61 | check_cxx_compiler_flag(-Wunused-parameter LIBCXXABI_HAS_WUNUSED_PARAMETER_FLAG) 62 | check_cxx_compiler_flag(-Wstrict-aliasing LIBCXXABI_HAS_WSTRICT_ALIASING_FLAG) 63 | check_cxx_compiler_flag(-Wstrict-overflow LIBCXXABI_HAS_WSTRICT_OVERFLOW_FLAG) 64 | check_cxx_compiler_flag(-Wwrite-strings LIBCXXABI_HAS_WWRITE_STRINGS_FLAG) 65 | check_cxx_compiler_flag(-Wchar-subscripts LIBCXXABI_HAS_WCHAR_SUBSCRIPTS_FLAG) 66 | check_cxx_compiler_flag(-Wmismatched-tags LIBCXXABI_HAS_WMISMATCHED_TAGS_FLAG) 67 | check_cxx_compiler_flag(-Wmissing-braces LIBCXXABI_HAS_WMISSING_BRACES_FLAG) 68 | check_cxx_compiler_flag(-Wshorten-64-to-32 LIBCXXABI_HAS_WSHORTEN_64_TO_32_FLAG) 69 | check_cxx_compiler_flag(-Wsign-conversion LIBCXXABI_HAS_WSIGN_CONVERSION_FLAG) 70 | check_cxx_compiler_flag(-Wsign-compare LIBCXXABI_HAS_WSIGN_COMPARE_FLAG) 71 | check_cxx_compiler_flag(-Wshadow LIBCXXABI_HAS_WSHADOW_FLAG) 72 | check_cxx_compiler_flag(-Wconversion LIBCXXABI_HAS_WCONVERSION_FLAG) 73 | check_cxx_compiler_flag(-Wnewline-eof LIBCXXABI_HAS_WNEWLINE_EOF_FLAG) 74 | check_cxx_compiler_flag(-Wundef LIBCXXABI_HAS_WUNDEF_FLAG) 75 | check_cxx_compiler_flag(-pedantic LIBCXXABI_HAS_PEDANTIC_FLAG) 76 | check_cxx_compiler_flag(-Werror LIBCXXABI_HAS_WERROR_FLAG) 77 | check_cxx_compiler_flag(-Wno-error LIBCXXABI_HAS_WNO_ERROR_FLAG) 78 | check_cxx_compiler_flag(/WX LIBCXXABI_HAS_WX_FLAG) 79 | check_cxx_compiler_flag(/WX- LIBCXXABI_HAS_NO_WX_FLAG) 80 | check_cxx_compiler_flag(/EHsc LIBCXXABI_HAS_EHSC_FLAG) 81 | check_cxx_compiler_flag(/EHs- LIBCXXABI_HAS_NO_EHS_FLAG) 82 | check_cxx_compiler_flag(/EHa- LIBCXXABI_HAS_NO_EHA_FLAG) 83 | check_cxx_compiler_flag(/GR- LIBCXXABI_HAS_NO_GR_FLAG) 84 | 85 | # Check libraries 86 | check_library_exists(dl dladdr "" LIBCXXABI_HAS_DL_LIB) 87 | check_library_exists(pthread pthread_once "" LIBCXXABI_HAS_PTHREAD_LIB) 88 | check_library_exists(c __cxa_thread_atexit_impl "" 89 | LIBCXXABI_HAS_CXA_THREAD_ATEXIT_IMPL) 90 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | cheerp-libcxxabi (2.5-1ubuntu1) bionic; urgency=medium 2 | 3 | * New release 4 | 5 | -- Alessandro Pignotti Sat, 04 Apr 2020 18:35:26 +0200 6 | 7 | cheerp-libcxxabi (2.0-1ubuntu1) bionic; urgency=medium 8 | 9 | * New release 10 | 11 | -- Alessandro Pignotti Wed, 13 Feb 2019 14:54:19 +0100 12 | 13 | cheerp-libcxxabi (2.0-rc2-1) artful; urgency=medium 14 | 15 | * New release 16 | 17 | -- Alessandro Pignotti Mon, 23 Apr 2018 15:01:08 +0200 18 | 19 | cheerp-libcxxabi (2.0-rc1-1) xenial; urgency=medium 20 | 21 | * New release 22 | 23 | -- Sander Mathijs van Veen Tue, 24 Oct 2017 11:30:34 +0200 24 | 25 | cheerp-libcxxabi (1.3-1) xenial; urgency=medium 26 | 27 | * New release 28 | 29 | -- Alessandro Pignotti Tue, 27 Sep 2016 09:48:12 +0200 30 | 31 | cheerp-libcxxabi (1.2-1) wily; urgency=medium 32 | 33 | * New release 34 | 35 | -- Alessandro Pignotti Thu, 21 Jan 2016 11:16:15 +0100 36 | 37 | cheerp-libcxxabi (1.1-1) utopic; urgency=medium 38 | 39 | * New release 40 | 41 | -- Alessandro Pignotti Wed, 03 Jun 2015 10:34:16 +0200 42 | 43 | cheerp-libcxxabi (1.0-1) trusty; urgency=medium 44 | 45 | * New release 46 | 47 | -- Alessandro Pignotti Wed, 21 May 2014 16:31:53 +0200 48 | 49 | cheerp-libcxxabi (0.9.6-1) saucy; urgency=low 50 | 51 | * New release 52 | 53 | -- Alessandro Pignotti Thu, 17 Apr 2014 17:27:01 +0200 54 | 55 | cheerp-libcxxabi (0.9.5-1) saucy; urgency=low 56 | 57 | * Update for release 58 | 59 | -- Alessandro Pignotti Thu, 03 Apr 2014 13:38:50 +0200 60 | 61 | cheerp-libcxxabi (0.9.4-1) saucy; urgency=low 62 | 63 | * New release 64 | 65 | -- Alessandro Pignotti Mon, 17 Mar 2014 02:06:50 +0100 66 | 67 | cheerp-libcxxabi (0.9.3-1) saucy; urgency=low 68 | 69 | * New release 70 | 71 | -- Alessandro Pignotti Thu, 02 Jan 2014 18:27:45 +0100 72 | 73 | cheerp-libcxxabi (0.9.2-1) saucy; urgency=low 74 | 75 | * New release 76 | 77 | -- Alessandro Pignotti Sat, 30 Nov 2013 20:05:05 +0100 78 | 79 | cheerp-libcxxabi (0.9.1) raring; urgency=low 80 | 81 | * Bump version 82 | 83 | -- Alessandro Pignotti Thu, 07 Nov 2013 23:11:22 +0100 84 | 85 | cheerp-libcxxabi (0.9-1) raring; urgency=low 86 | 87 | * Initial release 88 | 89 | -- Alessandro Pignotti Tue, 15 Oct 2013 18:10:49 +0200 90 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: cheerp-libcxxabi 2 | Maintainer: Alessandro Pignotti 3 | Section: devel 4 | Priority: optional 5 | Standards-Version: 3.9.2 6 | Build-Depends: debhelper (>=8), cmake, cheerp-llvm-clang (>=${source:Version}), cheerp-utils (>=${source:Version}), cheerp-newlib (>=${source:Version}), cheerp-libcxx (>=${source:Version}) 7 | 8 | Package: cheerp-libcxxabi 9 | Architecture: any 10 | Depends: ${shlibs:Depends}, ${misc:Depends}, cheerp-llvm-clang (>=${binary:Version}), cheerp-utils (>=${binary:Version}), cheerp-newlib (>=${binary:Version}), cheerp-libcxx (>=${binary:Version}) 11 | Conflicts: cheerp 12 | Description: A C++ compiler for the Web, C++ ABI implementation 13 | Cheerp is a tool to bring C++ programming to the Web. It can generate a seamless 14 | combination of JavaScript, WebAssembly and Asm.js from a single C++ codebase. 15 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Name: cheerp-libcxxabi 2 | Maintainer: Alessandro Pignotti 3 | Copyright: 2013, Alessandro Pignotti 4 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | LICENSE.TXT 2 | COPYING 3 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ -Scmake --parallel 5 | 6 | override_dh_auto_configure: 7 | dh_auto_configure -Bbuild_genericjs -- \ 8 | -DCMAKE_BUILD_TYPE=Release \ 9 | -DCMAKE_INSTALL_PREFIX=/opt/cheerp \ 10 | -DCMAKE_TOOLCHAIN_FILE=/opt/cheerp/share/cmake/Modules/CheerpToolchain.cmake \ 11 | -DCHEERP_LINEAR_OUTPUT=asmjs \ 12 | -DLIBCXXABI_ENABLE_SHARED=OFF \ 13 | -DLIBCXXABI_ENABLE_ASSERTIONS=OFF \ 14 | -DLIBCXXABI_LIBCXX_PATH=$(CURDIR)/libcxx/ \ 15 | -DLIBCXXABI_LIBCXX_INCLUDES=$(CURDIR)/libcxx/include/ \ 16 | -DLIBCXXABI_ENABLE_THREADS=0 \ 17 | -DLLVM_CONFIG=/opt/cheerp/bin/llvm-config 18 | dh_auto_configure -Bbuild_asmjs -- \ 19 | -DCMAKE_BUILD_TYPE=Release \ 20 | -DCMAKE_INSTALL_PREFIX=/opt/cheerp \ 21 | -DCMAKE_TOOLCHAIN_FILE=/opt/cheerp/share/cmake/Modules/CheerpWasmToolchain.cmake \ 22 | -DCHEERP_LINEAR_OUTPUT=asmjs \ 23 | -DLIBCXXABI_ENABLE_SHARED=OFF \ 24 | -DLIBCXXABI_ENABLE_ASSERTIONS=OFF \ 25 | -DLIBCXXABI_LIBCXX_PATH=$(CURDIR)/libcxx/ \ 26 | -DLIBCXXABI_LIBCXX_INCLUDES=$(CURDIR)/libcxx/include/ \ 27 | -DLIBCXXABI_ENABLE_THREADS=0 \ 28 | -DLLVM_CONFIG=/opt/cheerp/bin/llvm-config 29 | 30 | override_dh_auto_build: 31 | dh_auto_build -Bbuild_genericjs 32 | dh_auto_build -Bbuild_asmjs 33 | 34 | override_dh_auto_test: 35 | 36 | 37 | override_dh_auto_install: 38 | dh_auto_install -Bbuild_genericjs 39 | dh_auto_install -Bbuild_asmjs 40 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (quilt) 2 | -------------------------------------------------------------------------------- /fuzz/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # See http://llvm.org/docs/LibFuzzer.html 2 | if( LLVM_USE_SANITIZE_COVERAGE ) 3 | add_executable(cxa_demangle_fuzzer 4 | cxa_demangle_fuzzer.cpp 5 | ../src/cxa_demangle.cpp 6 | ) 7 | 8 | target_link_libraries(cxa_demangle_fuzzer 9 | LLVMFuzzer 10 | ) 11 | endif() 12 | -------------------------------------------------------------------------------- /fuzz/cxa_demangle_fuzzer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | extern "C" char * 6 | __cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status); 7 | 8 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 9 | char *str = new char[size+1]; 10 | memcpy(str, data, size); 11 | str[size] = 0; 12 | free(__cxa_demangle(str, 0, 0, 0)); 13 | delete [] str; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /include/__cxxabi_config.h: -------------------------------------------------------------------------------- 1 | //===-------------------------- __cxxabi_config.h -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef ____CXXABI_CONFIG_H 10 | #define ____CXXABI_CONFIG_H 11 | 12 | #if defined(__arm__) && !defined(__USING_SJLJ_EXCEPTIONS__) && \ 13 | !defined(__ARM_DWARF_EH__) 14 | #define _LIBCXXABI_ARM_EHABI 15 | #endif 16 | 17 | #if !defined(__has_attribute) 18 | #define __has_attribute(_attribute_) 0 19 | #endif 20 | 21 | #if defined(_WIN32) 22 | #if defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) 23 | #define _LIBCXXABI_HIDDEN 24 | #define _LIBCXXABI_DATA_VIS 25 | #define _LIBCXXABI_FUNC_VIS 26 | #define _LIBCXXABI_TYPE_VIS 27 | #elif defined(_LIBCXXABI_BUILDING_LIBRARY) 28 | #define _LIBCXXABI_HIDDEN 29 | #define _LIBCXXABI_DATA_VIS __declspec(dllexport) 30 | #define _LIBCXXABI_FUNC_VIS __declspec(dllexport) 31 | #define _LIBCXXABI_TYPE_VIS __declspec(dllexport) 32 | #else 33 | #define _LIBCXXABI_HIDDEN 34 | #define _LIBCXXABI_DATA_VIS __declspec(dllimport) 35 | #define _LIBCXXABI_FUNC_VIS __declspec(dllimport) 36 | #define _LIBCXXABI_TYPE_VIS __declspec(dllimport) 37 | #endif 38 | #else 39 | #if !defined(_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) 40 | #define _LIBCXXABI_HIDDEN __attribute__((__visibility__("hidden"))) 41 | #define _LIBCXXABI_DATA_VIS __attribute__((__visibility__("default"))) 42 | #define _LIBCXXABI_FUNC_VIS __attribute__((__visibility__("default"))) 43 | #if __has_attribute(__type_visibility__) 44 | #define _LIBCXXABI_TYPE_VIS __attribute__((__type_visibility__("default"))) 45 | #else 46 | #define _LIBCXXABI_TYPE_VIS __attribute__((__visibility__("default"))) 47 | #endif 48 | #else 49 | #define _LIBCXXABI_HIDDEN 50 | #define _LIBCXXABI_DATA_VIS 51 | #define _LIBCXXABI_FUNC_VIS 52 | #define _LIBCXXABI_TYPE_VIS 53 | #endif 54 | #endif 55 | 56 | #if defined(_WIN32) 57 | #define _LIBCXXABI_WEAK 58 | #else 59 | #define _LIBCXXABI_WEAK __attribute__((__weak__)) 60 | #endif 61 | 62 | #if defined(__clang__) 63 | #define _LIBCXXABI_COMPILER_CLANG 64 | #endif 65 | 66 | #if __has_attribute(__no_sanitize__) && defined(_LIBCXXABI_COMPILER_CLANG) 67 | #define _LIBCXXABI_NO_CFI __attribute__((__no_sanitize__("cfi"))) 68 | #else 69 | #define _LIBCXXABI_NO_CFI 70 | #endif 71 | 72 | #endif // ____CXXABI_CONFIG_H 73 | -------------------------------------------------------------------------------- /lib/buildit: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # 3 | # Set the $TRIPLE environment variable to your system's triple before 4 | # running this script. If you set $CXX, that will be used to compile 5 | # the library. Otherwise we'll use clang++. 6 | 7 | set -e 8 | 9 | if [ `basename $(pwd)` != "lib" ] 10 | then 11 | echo "current directory must be lib" 12 | exit 1 13 | fi 14 | 15 | if [ -z "$CXX" ] 16 | then 17 | CXX=clang++ 18 | fi 19 | 20 | if [ -z "$CC" ] 21 | then 22 | CC=clang 23 | fi 24 | 25 | if [ -z $RC_ProjectSourceVersion ] 26 | then 27 | RC_ProjectSourceVersion=1 28 | fi 29 | 30 | EXTRA_FLAGS="-std=c++11 -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 \ 31 | -Wsign-conversion -Wshadow -Wconversion -Wunused-variable \ 32 | -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags \ 33 | -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare \ 34 | -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter \ 35 | -Wnewline-eof -frtti" 36 | 37 | case $TRIPLE in 38 | *-apple-*) 39 | if [ -z $RC_XBS ] 40 | then 41 | RC_CFLAGS="-arch i386 -arch x86_64" 42 | fi 43 | SOEXT=dylib 44 | if [ -n "$SDKROOT" ] 45 | then 46 | EXTRA_FLAGS+="-isysroot ${SDKROOT}" 47 | CXX=`xcrun -sdk "${SDKROOT}" -find clang++` 48 | CC=`xcrun -sdk "${SDKROOT}" -find clang` 49 | fi 50 | LDSHARED_FLAGS="-o libc++abi.dylib \ 51 | -dynamiclib -nodefaultlibs \ 52 | -current_version ${RC_ProjectSourceVersion} \ 53 | -compatibility_version 1 \ 54 | -install_name /usr/lib/libc++abi.dylib \ 55 | -lSystem" 56 | if [ -f "${SDKROOT}/usr/local/lib/libCrashReporterClient.a" ] 57 | then 58 | LDSHARED_FLAGS+=" -lCrashReporterClient" 59 | fi 60 | ;; 61 | *-*-mingw*) 62 | # FIXME: removing libgcc and libsupc++ dependencies means porting libcxxrt and LLVM/compiler-rt 63 | SOEXT=dll 64 | LDSHARED_FLAGS="-o libc++abi.dll \ 65 | -shared -nodefaultlibs -Wl,--export-all-symbols -Wl,--allow-multiple-definition -Wl,--out-implib,libc++abi.dll.a \ 66 | -lsupc++ -lpthread -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcr100 -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt" 67 | ;; 68 | *) 69 | RC_CFLAGS="-fPIC" 70 | SOEXT=so 71 | LDSHARED_FLAGS="-o libc++abi.so.1.0 \ 72 | -shared -nodefaultlibs -Wl,-soname,libc++abi.so.1 \ 73 | -lpthread -lrt -lc -lstdc++" 74 | ;; 75 | esac 76 | 77 | if [ -z $RC_XBS ] 78 | then 79 | rm -f libc++abi.1.$SOEXT* 80 | fi 81 | 82 | set -x 83 | 84 | rm -f *.bc 85 | for FILE in ../src/*.cpp; do 86 | if [ "$FILE" == "../src/cxa_default_handlers.cpp" -o \ 87 | "$FILE" == "../src/cxa_exception.cpp" -o \ 88 | "$FILE" == "../src/cxa_handlers.cpp" -o \ 89 | "$FILE" == "../src/cxa_exception_storage.cpp" -o \ 90 | "$FILE" == "../src/cxa_unexpected.cpp" -o \ 91 | "$FILE" == "../src/cxa_personality.cpp" ] 92 | then 93 | echo "Skipping $FILE"; 94 | else 95 | $CXX -c -O3 $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE 96 | fi 97 | done 98 | case $TRIPLE in 99 | *-*-mingw*) 100 | for FILE in ../src/support/win32/*.cpp; do 101 | $CXX -c -g -Os $RC_CFLAGS $EXTRA_FLAGS -I../include $OPTIONS $FILE 102 | done 103 | ;; 104 | esac 105 | /opt/cheerp/bin/llvm-link *.bc -o libcxxabi.bc 106 | 107 | if [ -z $RC_XBS ] 108 | then 109 | rm -f *.o 110 | fi 111 | -------------------------------------------------------------------------------- /rpmbuild/.gitignore: -------------------------------------------------------------------------------- 1 | BUILD/ 2 | SOURCES/ 3 | SRPMS/ 4 | -------------------------------------------------------------------------------- /rpmbuild/SPECS/cheerp-libcxxabi.spec: -------------------------------------------------------------------------------- 1 | Name: cheerp-libcxxabi 2 | Version: 2.5 3 | Release: 1%{?dist} 4 | Summary: A C++ compiler for the Web, C++ ABI implementation 5 | 6 | License: GPLv2 7 | URL: https://leaningtech.com/cheerp 8 | Source0: %{NAME}_%{VERSION}.orig.tar.gz 9 | Source1: %{NAME}_%{VERSION}.orig-libcxx.tar.gz 10 | 11 | BuildRequires: cmake make cheerp-llvm-clang = %{VERSION} cheerp-utils = %{VERSION} cheerp-newlib = %{VERSION} cheerp-libcxx = %{VERSION} 12 | Requires: cheerp-llvm-clang = %{VERSION} cheerp-utils = %{VERSION} cheerp-newlib = %{VERSION} cheerp-libcxx = %{VERSION} 13 | 14 | %description 15 | Cheerp is a tool to bring C++ programming to the Web. It can generate a seamless 16 | combination of JavaScript, WebAssembly and Asm.js from a single C++ codebase. 17 | 18 | %define debug_package %{nil} 19 | 20 | %prep 21 | %autosetup 22 | %setup -T -D -a 1 23 | 24 | mkdir -p build_genericjs 25 | cd build_genericjs 26 | cmake -DCMAKE_INSTALL_PREFIX=/opt/cheerp -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/opt/cheerp/share/cmake/Modules/CheerpToolchain.cmake -DCHEERP_LINEAR_OUTPUT=asmjs -DLIBCXXABI_ENABLE_SHARED=OFF -DLIBCXXABI_ENABLE_ASSERTIONS=OFF -DLIBCXXABI_LIBCXX_PATH=$PWD/../libcxx/ -DLIBCXXABI_LIBCXX_INCLUDES=$PWD/../libcxx/include -DLIBCXXABI_ENABLE_THREADS=0 -DLLVM_CONFIG=/opt/cheerp/bin/llvm-config .. 27 | 28 | cd .. 29 | mkdir -p build_asmjs 30 | cd build_asmjs 31 | cmake -DCMAKE_INSTALL_PREFIX=/opt/cheerp -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=/opt/cheerp/share/cmake/Modules/CheerpWasmToolchain.cmake -DCHEERP_LINEAR_OUTPUT=asmjs -DLIBCXXABI_ENABLE_SHARED=OFF -DLIBCXXABI_ENABLE_ASSERTIONS=OFF -DLIBCXXABI_LIBCXX_PATH=$PWD/../libcxx/ -DLIBCXXABI_LIBCXX_INCLUDES=$PWD/../libcxx/include -DLIBCXXABI_ENABLE_THREADS=0 -DLLVM_CONFIG=/opt/cheerp/bin/llvm-config .. 32 | 33 | %build 34 | %make_build -C build_genericjs 35 | %make_build -C build_asmjs 36 | 37 | %install 38 | %make_install -C build_genericjs 39 | %make_install -C build_asmjs 40 | 41 | %clean 42 | rm -rf $RPM_BUILD_ROOT 43 | 44 | %files 45 | /opt/cheerp/ 46 | 47 | %changelog 48 | * Tue Dec 10 2019 Yuri Iozzelli 49 | - First RPM version 50 | -------------------------------------------------------------------------------- /src/abort_message.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- abort_message.cpp --------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include 10 | #include 11 | #include 12 | #include "abort_message.h" 13 | 14 | #ifdef __BIONIC__ 15 | #include 16 | #if __ANDROID_API__ >= 21 17 | #include 18 | extern "C" void android_set_abort_message(const char* msg); 19 | #else 20 | #include 21 | #endif // __ANDROID_API__ >= 21 22 | #endif // __BIONIC__ 23 | 24 | #ifdef __APPLE__ 25 | # if defined(__has_include) && __has_include() 26 | # define HAVE_CRASHREPORTERCLIENT_H 27 | # include 28 | # endif 29 | #endif 30 | 31 | void abort_message(const char* format, ...) 32 | { 33 | #ifndef __CHEERP__ 34 | // write message to stderr 35 | #if !defined(NDEBUG) || !defined(LIBCXXABI_BAREMETAL) 36 | #ifdef __APPLE__ 37 | fprintf(stderr, "libc++abi.dylib: "); 38 | #endif 39 | va_list list; 40 | va_start(list, format); 41 | vfprintf(stderr, format, list); 42 | va_end(list); 43 | fprintf(stderr, "\n"); 44 | #endif 45 | 46 | #if defined(__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H) 47 | // record message in crash report 48 | char* buffer; 49 | va_list list2; 50 | va_start(list2, format); 51 | vasprintf(&buffer, format, list2); 52 | va_end(list2); 53 | CRSetCrashLogMessage(buffer); 54 | #elif defined(__BIONIC__) 55 | char* buffer; 56 | va_list list2; 57 | va_start(list2, format); 58 | vasprintf(&buffer, format, list2); 59 | va_end(list2); 60 | 61 | #if __ANDROID_API__ >= 21 62 | // Show error in tombstone. 63 | android_set_abort_message(buffer); 64 | 65 | // Show error in logcat. 66 | openlog("libc++abi", 0, 0); 67 | syslog(LOG_CRIT, "%s", buffer); 68 | closelog(); 69 | #else 70 | // The good error reporting wasn't available in Android until L. Since we're 71 | // about to abort anyway, just call __assert2, which will log _somewhere_ 72 | // (tombstone and/or logcat) in older releases. 73 | __assert2(__FILE__, __LINE__, __func__, buffer); 74 | #endif // __ANDROID_API__ >= 21 75 | #endif // __BIONIC__ 76 | #endif // !__CHEERP__ 77 | 78 | abort(); 79 | } 80 | -------------------------------------------------------------------------------- /src/abort_message.h: -------------------------------------------------------------------------------- 1 | //===-------------------------- abort_message.h-----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef __ABORT_MESSAGE_H_ 10 | #define __ABORT_MESSAGE_H_ 11 | 12 | #include "cxxabi.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN void 19 | abort_message(const char *format, ...) __attribute__((format(printf, 1, 2))); 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /src/cxa_aux_runtime.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------ cxa_aux_runtime.cpp -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // 8 | // This file implements the "Auxiliary Runtime APIs" 9 | // http://mentorembedded.github.io/cxx-abi/abi-eh.html#cxx-aux 10 | //===----------------------------------------------------------------------===// 11 | 12 | #include "cxxabi.h" 13 | #include 14 | #include 15 | 16 | namespace __cxxabiv1 { 17 | extern "C" { 18 | _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_cast(void) { 19 | #ifndef _LIBCXXABI_NO_EXCEPTIONS 20 | #ifndef __CHEERP__ 21 | throw std::bad_cast(); 22 | #endif 23 | #else 24 | std::terminate(); 25 | #endif 26 | } 27 | 28 | _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void __cxa_bad_typeid(void) { 29 | #ifndef _LIBCXXABI_NO_EXCEPTIONS 30 | #ifndef __CHEERP__ 31 | throw std::bad_typeid(); 32 | #endif 33 | #else 34 | std::terminate(); 35 | #endif 36 | } 37 | 38 | _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN void 39 | __cxa_throw_bad_array_new_length(void) { 40 | #ifndef _LIBCXXABI_NO_EXCEPTIONS 41 | #ifndef __CHEERP__ 42 | throw std::bad_array_new_length(); 43 | #endif 44 | #else 45 | std::terminate(); 46 | #endif 47 | } 48 | } // extern "C" 49 | } // abi 50 | -------------------------------------------------------------------------------- /src/cxa_default_handlers.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- cxa_default_handlers.cpp -------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // 8 | // This file implements the default terminate_handler and unexpected_handler. 9 | //===----------------------------------------------------------------------===// 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "abort_message.h" 16 | #include "cxxabi.h" 17 | #include "cxa_handlers.hpp" 18 | #include "cxa_exception.hpp" 19 | #include "private_typeinfo.h" 20 | #include "include/atomic_support.h" 21 | 22 | #if !defined(LIBCXXABI_SILENT_TERMINATE) 23 | static const char* cause = "uncaught"; 24 | 25 | __attribute__((noreturn)) 26 | static void demangling_terminate_handler() 27 | { 28 | // If there might be an uncaught exception 29 | using namespace __cxxabiv1; 30 | __cxa_eh_globals* globals = __cxa_get_globals_fast(); 31 | if (globals) 32 | { 33 | __cxa_exception* exception_header = globals->caughtExceptions; 34 | // If there is an uncaught exception 35 | if (exception_header) 36 | { 37 | _Unwind_Exception* unwind_exception = 38 | reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; 39 | if (__isOurExceptionClass(unwind_exception)) 40 | { 41 | void* thrown_object = 42 | __getExceptionClass(unwind_exception) == kOurDependentExceptionClass ? 43 | ((__cxa_dependent_exception*)exception_header)->primaryException : 44 | exception_header + 1; 45 | const __shim_type_info* thrown_type = 46 | static_cast(exception_header->exceptionType); 47 | // Try to get demangled name of thrown_type 48 | int status; 49 | char buf[1024]; 50 | size_t len = sizeof(buf); 51 | const char* name = __cxa_demangle(thrown_type->name(), buf, &len, &status); 52 | if (status != 0) 53 | name = thrown_type->name(); 54 | // If the uncaught exception can be caught with std::exception& 55 | const __shim_type_info* catch_type = 56 | static_cast(&typeid(std::exception)); 57 | if (catch_type->can_catch(thrown_type, thrown_object)) 58 | { 59 | // Include the what() message from the exception 60 | const std::exception* e = static_cast(thrown_object); 61 | abort_message("terminating with %s exception of type %s: %s", 62 | cause, name, e->what()); 63 | } 64 | else 65 | // Else just note that we're terminating with an exception 66 | abort_message("terminating with %s exception of type %s", 67 | cause, name); 68 | } 69 | else 70 | // Else we're terminating with a foreign exception 71 | abort_message("terminating with %s foreign exception", cause); 72 | } 73 | } 74 | // Else just note that we're terminating 75 | abort_message("terminating"); 76 | } 77 | 78 | __attribute__((noreturn)) 79 | static void demangling_unexpected_handler() 80 | { 81 | cause = "unexpected"; 82 | std::terminate(); 83 | } 84 | 85 | static std::terminate_handler default_terminate_handler = demangling_terminate_handler; 86 | static std::terminate_handler default_unexpected_handler = demangling_unexpected_handler; 87 | #else 88 | static std::terminate_handler default_terminate_handler = std::abort; 89 | static std::terminate_handler default_unexpected_handler = std::terminate; 90 | #endif 91 | 92 | // 93 | // Global variables that hold the pointers to the current handler 94 | // 95 | _LIBCXXABI_DATA_VIS 96 | std::terminate_handler __cxa_terminate_handler = default_terminate_handler; 97 | 98 | _LIBCXXABI_DATA_VIS 99 | std::unexpected_handler __cxa_unexpected_handler = default_unexpected_handler; 100 | 101 | namespace std 102 | { 103 | 104 | unexpected_handler 105 | set_unexpected(unexpected_handler func) _NOEXCEPT 106 | { 107 | if (func == 0) 108 | func = default_unexpected_handler; 109 | return __libcpp_atomic_exchange(&__cxa_unexpected_handler, func, 110 | _AO_Acq_Rel); 111 | } 112 | 113 | terminate_handler 114 | set_terminate(terminate_handler func) _NOEXCEPT 115 | { 116 | if (func == 0) 117 | func = default_terminate_handler; 118 | return __libcpp_atomic_exchange(&__cxa_terminate_handler, func, 119 | _AO_Acq_Rel); 120 | } 121 | 122 | } 123 | -------------------------------------------------------------------------------- /src/cxa_exception.hpp: -------------------------------------------------------------------------------- 1 | //===------------------------- cxa_exception.hpp --------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // 8 | // This file implements the "Exception Handling APIs" 9 | // http://mentorembedded.github.io/cxx-abi/abi-eh.html 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef _CXA_EXCEPTION_H 14 | #define _CXA_EXCEPTION_H 15 | 16 | #include // for std::unexpected_handler and std::terminate_handler 17 | #include "cxxabi.h" 18 | #include "unwind.h" 19 | 20 | namespace __cxxabiv1 { 21 | 22 | static const uint64_t kOurExceptionClass = 0x434C4E47432B2B00; // CLNGC++\0 23 | static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1 24 | static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++ 25 | 26 | uint64_t __getExceptionClass (const _Unwind_Exception*); 27 | void __setExceptionClass ( _Unwind_Exception*, uint64_t); 28 | bool __isOurExceptionClass(const _Unwind_Exception*); 29 | 30 | struct _LIBCXXABI_HIDDEN __cxa_exception { 31 | #if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI) 32 | // This is a new field to support C++ 0x exception_ptr. 33 | // For binary compatibility it is at the start of this 34 | // struct which is prepended to the object thrown in 35 | // __cxa_allocate_exception. 36 | size_t referenceCount; 37 | #endif 38 | 39 | // Manage the exception object itself. 40 | std::type_info *exceptionType; 41 | void (*exceptionDestructor)(void *); 42 | std::unexpected_handler unexpectedHandler; 43 | std::terminate_handler terminateHandler; 44 | 45 | __cxa_exception *nextException; 46 | 47 | int handlerCount; 48 | 49 | #if defined(_LIBCXXABI_ARM_EHABI) 50 | __cxa_exception* nextPropagatingException; 51 | int propagationCount; 52 | #else 53 | int handlerSwitchValue; 54 | const unsigned char *actionRecord; 55 | const unsigned char *languageSpecificData; 56 | void *catchTemp; 57 | void *adjustedPtr; 58 | #endif 59 | 60 | #if !defined(__LP64__) && !defined(_LIBCXXABI_ARM_EHABI) 61 | // This is a new field to support C++ 0x exception_ptr. 62 | // For binary compatibility it is placed where the compiler 63 | // previously adding padded to 64-bit align unwindHeader. 64 | size_t referenceCount; 65 | #endif 66 | _Unwind_Exception unwindHeader; 67 | }; 68 | 69 | // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html 70 | // The layout of this structure MUST match the layout of __cxa_exception, with 71 | // primaryException instead of referenceCount. 72 | struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { 73 | #if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI) 74 | void* primaryException; 75 | #endif 76 | 77 | std::type_info *exceptionType; 78 | void (*exceptionDestructor)(void *); 79 | std::unexpected_handler unexpectedHandler; 80 | std::terminate_handler terminateHandler; 81 | 82 | __cxa_exception *nextException; 83 | 84 | int handlerCount; 85 | 86 | #if defined(_LIBCXXABI_ARM_EHABI) 87 | __cxa_exception* nextPropagatingException; 88 | int propagationCount; 89 | #else 90 | int handlerSwitchValue; 91 | const unsigned char *actionRecord; 92 | const unsigned char *languageSpecificData; 93 | void * catchTemp; 94 | void *adjustedPtr; 95 | #endif 96 | 97 | #if !defined(__LP64__) && !defined(_LIBCXXABI_ARM_EHABI) 98 | void* primaryException; 99 | #endif 100 | _Unwind_Exception unwindHeader; 101 | }; 102 | 103 | struct _LIBCXXABI_HIDDEN __cxa_eh_globals { 104 | __cxa_exception * caughtExceptions; 105 | unsigned int uncaughtExceptions; 106 | #if defined(_LIBCXXABI_ARM_EHABI) 107 | __cxa_exception* propagatingExceptions; 108 | #endif 109 | }; 110 | 111 | extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals (); 112 | extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals_fast (); 113 | 114 | extern "C" _LIBCXXABI_FUNC_VIS void * __cxa_allocate_dependent_exception (); 115 | extern "C" _LIBCXXABI_FUNC_VIS void __cxa_free_dependent_exception (void * dependent_exception); 116 | 117 | } // namespace __cxxabiv1 118 | 119 | #endif // _CXA_EXCEPTION_H 120 | -------------------------------------------------------------------------------- /src/cxa_exception_storage.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------- cxa_exception_storage.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // 8 | // This file implements the storage for the "Caught Exception Stack" 9 | // http://mentorembedded.github.io/cxx-abi/abi-eh.html (section 2.2.2) 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #include "cxa_exception.hpp" 14 | 15 | #include <__threading_support> 16 | 17 | #if defined(_LIBCXXABI_HAS_NO_THREADS) 18 | 19 | namespace __cxxabiv1 { 20 | extern "C" { 21 | static __cxa_eh_globals eh_globals; 22 | __cxa_eh_globals *__cxa_get_globals() { return &eh_globals; } 23 | __cxa_eh_globals *__cxa_get_globals_fast() { return &eh_globals; } 24 | } 25 | } 26 | 27 | #elif defined(HAS_THREAD_LOCAL) 28 | 29 | namespace __cxxabiv1 { 30 | 31 | namespace { 32 | __cxa_eh_globals * __globals () { 33 | static thread_local __cxa_eh_globals eh_globals; 34 | return &eh_globals; 35 | } 36 | } 37 | 38 | extern "C" { 39 | __cxa_eh_globals * __cxa_get_globals () { return __globals (); } 40 | __cxa_eh_globals * __cxa_get_globals_fast () { return __globals (); } 41 | } 42 | } 43 | 44 | #else 45 | 46 | #include "abort_message.h" 47 | #include "fallback_malloc.h" 48 | 49 | // In general, we treat all threading errors as fatal. 50 | // We cannot call std::terminate() because that will in turn 51 | // call __cxa_get_globals() and cause infinite recursion. 52 | 53 | namespace __cxxabiv1 { 54 | namespace { 55 | std::__libcpp_tls_key key_; 56 | std::__libcpp_exec_once_flag flag_ = _LIBCPP_EXEC_ONCE_INITIALIZER; 57 | 58 | void _LIBCPP_TLS_DESTRUCTOR_CC destruct_ (void *p) { 59 | __free_with_fallback ( p ); 60 | if ( 0 != std::__libcpp_tls_set ( key_, NULL ) ) 61 | abort_message("cannot zero out thread value for __cxa_get_globals()"); 62 | } 63 | 64 | void construct_ () { 65 | if ( 0 != std::__libcpp_tls_create ( &key_, destruct_ ) ) 66 | abort_message("cannot create thread specific key for __cxa_get_globals()"); 67 | } 68 | } 69 | 70 | extern "C" { 71 | __cxa_eh_globals * __cxa_get_globals () { 72 | // Try to get the globals for this thread 73 | __cxa_eh_globals* retVal = __cxa_get_globals_fast (); 74 | 75 | // If this is the first time we've been asked for these globals, create them 76 | if ( NULL == retVal ) { 77 | retVal = static_cast<__cxa_eh_globals*> 78 | (__calloc_with_fallback (1, sizeof (__cxa_eh_globals))); 79 | if ( NULL == retVal ) 80 | abort_message("cannot allocate __cxa_eh_globals"); 81 | if ( 0 != std::__libcpp_tls_set ( key_, retVal ) ) 82 | abort_message("std::__libcpp_tls_set failure in __cxa_get_globals()"); 83 | } 84 | return retVal; 85 | } 86 | 87 | // Note that this implementation will reliably return NULL if not 88 | // preceded by a call to __cxa_get_globals(). This is an extension 89 | // to the Itanium ABI and is taken advantage of in several places in 90 | // libc++abi. 91 | __cxa_eh_globals * __cxa_get_globals_fast () { 92 | // First time through, create the key. 93 | if (0 != std::__libcpp_execute_once(&flag_, construct_)) 94 | abort_message("execute once failure in __cxa_get_globals_fast()"); 95 | // static int init = construct_(); 96 | return static_cast<__cxa_eh_globals*>(std::__libcpp_tls_get(key_)); 97 | } 98 | 99 | } 100 | } 101 | #endif 102 | -------------------------------------------------------------------------------- /src/cxa_handlers.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- cxa_handlers.cpp ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // 8 | // This file implements the functionality associated with the terminate_handler, 9 | // unexpected_handler, and new_handler. 10 | //===----------------------------------------------------------------------===// 11 | 12 | #include 13 | #include 14 | #include 15 | #include "abort_message.h" 16 | #include "cxxabi.h" 17 | #include "cxa_handlers.hpp" 18 | #include "cxa_exception.hpp" 19 | #include "private_typeinfo.h" 20 | #include "include/atomic_support.h" 21 | 22 | namespace std 23 | { 24 | 25 | unexpected_handler 26 | get_unexpected() _NOEXCEPT 27 | { 28 | return __libcpp_atomic_load(&__cxa_unexpected_handler, _AO_Acquire); 29 | } 30 | 31 | void 32 | __unexpected(unexpected_handler func) 33 | { 34 | func(); 35 | // unexpected handler should not return 36 | abort_message("unexpected_handler unexpectedly returned"); 37 | } 38 | 39 | __attribute__((noreturn)) 40 | void 41 | unexpected() 42 | { 43 | __unexpected(get_unexpected()); 44 | } 45 | 46 | terminate_handler 47 | get_terminate() _NOEXCEPT 48 | { 49 | return __libcpp_atomic_load(&__cxa_terminate_handler, _AO_Acquire); 50 | } 51 | 52 | void 53 | __terminate(terminate_handler func) _NOEXCEPT 54 | { 55 | #ifndef _LIBCXXABI_NO_EXCEPTIONS 56 | try 57 | { 58 | #endif // _LIBCXXABI_NO_EXCEPTIONS 59 | func(); 60 | // handler should not return 61 | abort_message("terminate_handler unexpectedly returned"); 62 | #ifndef _LIBCXXABI_NO_EXCEPTIONS 63 | } 64 | catch (...) 65 | { 66 | // handler should not throw exception 67 | abort_message("terminate_handler unexpectedly threw an exception"); 68 | } 69 | #endif // _LIBCXXABI_NO_EXCEPTIONS 70 | } 71 | 72 | __attribute__((noreturn)) 73 | void 74 | terminate() _NOEXCEPT 75 | { 76 | // If there might be an uncaught exception 77 | using namespace __cxxabiv1; 78 | __cxa_eh_globals* globals = __cxa_get_globals_fast(); 79 | if (globals) 80 | { 81 | __cxa_exception* exception_header = globals->caughtExceptions; 82 | if (exception_header) 83 | { 84 | _Unwind_Exception* unwind_exception = 85 | reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; 86 | if (__isOurExceptionClass(unwind_exception)) 87 | __terminate(exception_header->terminateHandler); 88 | } 89 | } 90 | __terminate(get_terminate()); 91 | } 92 | 93 | extern "C" { 94 | new_handler __cxa_new_handler = 0; 95 | } 96 | 97 | new_handler 98 | set_new_handler(new_handler handler) _NOEXCEPT 99 | { 100 | return __libcpp_atomic_exchange(&__cxa_new_handler, handler, _AO_Acq_Rel); 101 | } 102 | 103 | new_handler 104 | get_new_handler() _NOEXCEPT 105 | { 106 | return __libcpp_atomic_load(&__cxa_new_handler, _AO_Acquire); 107 | } 108 | 109 | } // std 110 | -------------------------------------------------------------------------------- /src/cxa_handlers.hpp: -------------------------------------------------------------------------------- 1 | //===------------------------- cxa_handlers.cpp ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // 8 | // This file implements the functionality associated with the terminate_handler, 9 | // unexpected_handler, and new_handler. 10 | //===----------------------------------------------------------------------===// 11 | 12 | #ifndef _CXA_HANDLERS_H 13 | #define _CXA_HANDLERS_H 14 | 15 | #include <__cxxabi_config.h> 16 | 17 | #include 18 | 19 | namespace std 20 | { 21 | 22 | _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN 23 | void 24 | __unexpected(unexpected_handler func); 25 | 26 | _LIBCXXABI_HIDDEN _LIBCXXABI_NORETURN 27 | void 28 | __terminate(terminate_handler func) _NOEXCEPT; 29 | 30 | } // std 31 | 32 | extern "C" 33 | { 34 | 35 | _LIBCXXABI_DATA_VIS extern void (*__cxa_terminate_handler)(); 36 | _LIBCXXABI_DATA_VIS extern void (*__cxa_unexpected_handler)(); 37 | _LIBCXXABI_DATA_VIS extern void (*__cxa_new_handler)(); 38 | 39 | /* 40 | 41 | At some point in the future these three symbols will become 42 | C++11 atomic variables: 43 | 44 | extern std::atomic __cxa_terminate_handler; 45 | extern std::atomic __cxa_unexpected_handler; 46 | extern std::atomic __cxa_new_handler; 47 | 48 | This change will not impact their ABI. But it will allow for a 49 | portable performance optimization. 50 | 51 | */ 52 | 53 | } // extern "C" 54 | 55 | #endif // _CXA_HANDLERS_H 56 | -------------------------------------------------------------------------------- /src/cxa_noexception.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- cxa_exception.cpp --------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // 8 | // This file implements the "Exception Handling APIs" 9 | // http://mentorembedded.github.io/cxx-abi/abi-eh.html 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | // Support functions for the no-exceptions libc++ library 14 | 15 | #include "cxxabi.h" 16 | 17 | #include // for std::terminate 18 | #include "cxa_exception.hpp" 19 | #include "cxa_handlers.hpp" 20 | 21 | namespace __cxxabiv1 { 22 | 23 | extern "C" { 24 | 25 | void 26 | __cxa_increment_exception_refcount(void *thrown_object) throw() { 27 | if (thrown_object != nullptr) 28 | std::terminate(); 29 | } 30 | 31 | void 32 | __cxa_decrement_exception_refcount(void *thrown_object) throw() { 33 | if (thrown_object != nullptr) 34 | std::terminate(); 35 | } 36 | 37 | 38 | void *__cxa_current_primary_exception() throw() { return nullptr; } 39 | 40 | void 41 | __cxa_rethrow_primary_exception(void* thrown_object) { 42 | if (thrown_object != nullptr) 43 | std::terminate(); 44 | } 45 | 46 | bool 47 | __cxa_uncaught_exception() throw() { return false; } 48 | 49 | unsigned int 50 | __cxa_uncaught_exceptions() throw() { return 0; } 51 | 52 | } // extern "C" 53 | 54 | // provide dummy implementations for the 'no exceptions' case. 55 | uint64_t __getExceptionClass (const _Unwind_Exception*) { return 0; } 56 | void __setExceptionClass ( _Unwind_Exception*, uint64_t) {} 57 | bool __isOurExceptionClass(const _Unwind_Exception*) { return false; } 58 | 59 | } // abi 60 | -------------------------------------------------------------------------------- /src/cxa_thread_atexit.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- cxa_thread_atexit.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include "abort_message.h" 10 | #include "cxxabi.h" 11 | #include <__threading_support> 12 | #include 13 | 14 | namespace __cxxabiv1 { 15 | 16 | using Dtor = void(*)(void*); 17 | 18 | extern "C" 19 | #ifndef HAVE___CXA_THREAD_ATEXIT_IMPL 20 | // A weak symbol is used to detect this function's presence in the C library 21 | // at runtime, even if libc++ is built against an older libc 22 | _LIBCXXABI_WEAK 23 | #endif 24 | int __cxa_thread_atexit_impl(Dtor, void*, void*); 25 | 26 | #ifndef HAVE___CXA_THREAD_ATEXIT_IMPL 27 | 28 | namespace { 29 | // This implementation is used if the C library does not provide 30 | // __cxa_thread_atexit_impl() for us. It has a number of limitations that are 31 | // difficult to impossible to address without ..._impl(): 32 | // 33 | // - dso_symbol is ignored. This means that a shared library may be unloaded 34 | // (via dlclose()) before its thread_local destructors have run. 35 | // 36 | // - thread_local destructors for the main thread are run by the destructor of 37 | // a static object. This is later than expected; they should run before the 38 | // destructors of any objects with static storage duration. 39 | // 40 | // - thread_local destructors on non-main threads run on the first iteration 41 | // through the __libccpp_tls_key destructors. 42 | // std::notify_all_at_thread_exit() and similar functions must be careful to 43 | // wait until the second iteration to provide their intended ordering 44 | // guarantees. 45 | // 46 | // Another limitation, though one shared with ..._impl(), is that any 47 | // thread_locals that are first initialized after non-thread_local global 48 | // destructors begin to run will not be destroyed. [basic.start.term] states 49 | // that all thread_local destructors are sequenced before the destruction of 50 | // objects with static storage duration, resulting in a contradiction if a 51 | // thread_local is constructed after that point. Thus we consider such 52 | // programs ill-formed, and don't bother to run those destructors. (If the 53 | // program terminates abnormally after such a thread_local is constructed, 54 | // the destructor is not expected to run and thus there is no contradiction. 55 | // So construction still has to work.) 56 | 57 | struct DtorList { 58 | Dtor dtor; 59 | void* obj; 60 | DtorList* next; 61 | }; 62 | 63 | // The linked list of thread-local destructors to run 64 | __thread DtorList* dtors = nullptr; 65 | // True if the destructors are currently scheduled to run on this thread 66 | __thread bool dtors_alive = false; 67 | // Used to trigger destructors on thread exit; value is ignored 68 | std::__libcpp_tls_key dtors_key; 69 | 70 | void run_dtors(void*) { 71 | while (auto head = dtors) { 72 | dtors = head->next; 73 | head->dtor(head->obj); 74 | std::free(head); 75 | } 76 | 77 | dtors_alive = false; 78 | } 79 | 80 | struct DtorsManager { 81 | DtorsManager() { 82 | // There is intentionally no matching std::__libcpp_tls_delete call, as 83 | // __cxa_thread_atexit() may be called arbitrarily late (for example, from 84 | // global destructors or atexit() handlers). 85 | if (std::__libcpp_tls_create(&dtors_key, run_dtors) != 0) { 86 | abort_message("std::__libcpp_tls_create() failed in __cxa_thread_atexit()"); 87 | } 88 | } 89 | 90 | ~DtorsManager() { 91 | // std::__libcpp_tls_key destructors do not run on threads that call exit() 92 | // (including when the main thread returns from main()), so we explicitly 93 | // call the destructor here. This runs at exit time (potentially earlier 94 | // if libc++abi is dlclose()'d). Any thread_locals initialized after this 95 | // point will not be destroyed. 96 | run_dtors(nullptr); 97 | } 98 | }; 99 | } // namespace 100 | 101 | #endif // HAVE___CXA_THREAD_ATEXIT_IMPL 102 | 103 | extern "C" { 104 | 105 | _LIBCXXABI_FUNC_VIS int __cxa_thread_atexit(Dtor dtor, void* obj, void* dso_symbol) throw() { 106 | #ifdef HAVE___CXA_THREAD_ATEXIT_IMPL 107 | return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); 108 | #else 109 | if (__cxa_thread_atexit_impl) { 110 | return __cxa_thread_atexit_impl(dtor, obj, dso_symbol); 111 | } else { 112 | // Initialize the dtors std::__libcpp_tls_key (uses __cxa_guard_*() for 113 | // one-time initialization and __cxa_atexit() for destruction) 114 | static DtorsManager manager; 115 | 116 | if (!dtors_alive) { 117 | if (std::__libcpp_tls_set(dtors_key, &dtors_key) != 0) { 118 | return -1; 119 | } 120 | dtors_alive = true; 121 | } 122 | 123 | auto head = static_cast(std::malloc(sizeof(DtorList))); 124 | if (!head) { 125 | return -1; 126 | } 127 | 128 | head->dtor = dtor; 129 | head->obj = obj; 130 | head->next = dtors; 131 | dtors = head; 132 | 133 | return 0; 134 | } 135 | #endif // HAVE___CXA_THREAD_ATEXIT_IMPL 136 | } 137 | 138 | } // extern "C" 139 | } // namespace __cxxabiv1 140 | -------------------------------------------------------------------------------- /src/cxa_unexpected.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- cxa_unexpected.cpp -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include 10 | #include "cxxabi.h" 11 | #include "cxa_exception.hpp" 12 | 13 | namespace __cxxabiv1 14 | { 15 | 16 | extern "C" 17 | { 18 | 19 | } 20 | 21 | } // namespace __cxxabiv1 22 | 23 | -------------------------------------------------------------------------------- /src/cxa_virtual.cpp: -------------------------------------------------------------------------------- 1 | //===-------------------------- cxa_virtual.cpp ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include "cxxabi.h" 10 | #include "abort_message.h" 11 | 12 | namespace __cxxabiv1 { 13 | extern "C" { 14 | _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN 15 | void __cxa_pure_virtual(void) { 16 | abort_message("Pure virtual function called!"); 17 | } 18 | 19 | _LIBCXXABI_FUNC_VIS _LIBCXXABI_NORETURN 20 | void __cxa_deleted_virtual(void) { 21 | abort_message("Deleted virtual function called!"); 22 | } 23 | } // extern "C" 24 | } // abi 25 | -------------------------------------------------------------------------------- /src/demangle/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: LLVM 2 | 3 | -------------------------------------------------------------------------------- /src/demangle/DemangleConfig.h: -------------------------------------------------------------------------------- 1 | //===--- Compiler.h ---------------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | // This file is contains a subset of macros copied from 8 | // llvm/lib/Demangle/Compiler.h. 9 | //===----------------------------------------------------------------------===// 10 | 11 | #ifndef LIBCXX_DEMANGLE_COMPILER_H 12 | #define LIBCXX_DEMANGLE_COMPILER_H 13 | 14 | #include "__config" 15 | 16 | #ifdef _MSC_VER 17 | // snprintf is implemented in VS 2015 18 | #if _MSC_VER < 1900 19 | #define snprintf _snprintf_s 20 | #endif 21 | #endif 22 | 23 | #ifndef __has_attribute 24 | #define __has_attribute(x) 0 25 | #endif 26 | 27 | #ifndef NDEBUG 28 | #if __has_attribute(noinline) && __has_attribute(used) 29 | #define DEMANGLE_DUMP_METHOD __attribute__((noinline, used)) 30 | #else 31 | #define DEMANGLE_DUMP_METHOD 32 | #endif 33 | #endif 34 | 35 | #define DEMANGLE_FALLTHROUGH _LIBCPP_FALLTHROUGH() 36 | #define DEMANGLE_UNREACHABLE _LIBCPP_UNREACHABLE() 37 | 38 | #define DEMANGLE_NAMESPACE_BEGIN namespace { namespace itanium_demangle { 39 | #define DEMANGLE_NAMESPACE_END } } 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/demangle/README.txt: -------------------------------------------------------------------------------- 1 | Itanium Name Demangler Library 2 | ============================== 3 | 4 | Introduction 5 | ------------ 6 | 7 | This directory contains the generic itanium name demangler library. The main 8 | purpose of the library is to demangle C++ symbols, i.e. convert the string 9 | "_Z1fv" into "f()". You can also use the CRTP base ManglingParser to perform 10 | some simple analysis on the mangled name, or (in LLVM) use the opaque 11 | ItaniumPartialDemangler to query the demangled AST. 12 | 13 | Why are there multiple copies of the this library in the source tree? 14 | --------------------------------------------------------------------- 15 | 16 | This directory is mirrored between libcxxabi/demangle and 17 | llvm/include/llvm/Demangle. The simple reason for this is that both projects 18 | need to demangle symbols, but neither can depend on each other. libcxxabi needs 19 | the demangler to implement __cxa_demangle, which is part of the itanium ABI 20 | spec. LLVM needs a copy for a bunch of places, but doesn't want to use the 21 | system's __cxa_demangle because it a) might not be available (i.e., on Windows), 22 | and b) probably isn't that up-to-date on the latest language features. 23 | 24 | The copy of the demangler in LLVM has some extra stuff that aren't needed in 25 | libcxxabi (ie, the MSVC demangler, ItaniumPartialDemangler), which depend on the 26 | shared generic components. Despite these differences, we want to keep the "core" 27 | generic demangling library identical between both copies to simplify development 28 | and testing. 29 | 30 | If you're working on the generic library, then do the work first in libcxxabi, 31 | then run the cp-to-llvm.sh script in src/demangle. This script takes as an 32 | argument the path to llvm, and re-copies the changes you made to libcxxabi over. 33 | Note that this script just blindly overwrites all changes to the generic library 34 | in llvm, so be careful. 35 | 36 | Because the core demangler needs to work in libcxxabi, everything needs to be 37 | declared in an anonymous namespace (see DEMANGLE_NAMESPACE_BEGIN), and you can't 38 | introduce any code that depends on the libcxx dylib. 39 | 40 | Hopefully, when LLVM becomes a monorepo, we can de-duplicate this code, and have 41 | both LLVM and libcxxabi depend on a shared demangler library. 42 | 43 | Testing 44 | ------- 45 | 46 | The tests are split up between libcxxabi/test/{unit,}test_demangle.cpp, and 47 | llvm/unittest/Demangle. The llvm directory should only get tests for stuff not 48 | included in the core library. In the future though, we should probably move all 49 | the tests to LLVM. 50 | 51 | It is also a really good idea to run libFuzzer after non-trivial changes, see 52 | libcxxabi/fuzz/cxa_demangle_fuzzer.cpp and https://llvm.org/docs/LibFuzzer.html. 53 | -------------------------------------------------------------------------------- /src/demangle/StringView.h: -------------------------------------------------------------------------------- 1 | //===--- StringView.h -------------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // FIXME: Use std::string_view instead when we support C++17. 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef DEMANGLE_STRINGVIEW_H 14 | #define DEMANGLE_STRINGVIEW_H 15 | 16 | #include "DemangleConfig.h" 17 | #include 18 | #include 19 | #include 20 | 21 | DEMANGLE_NAMESPACE_BEGIN 22 | 23 | class StringView { 24 | const char *First; 25 | const char *Last; 26 | 27 | public: 28 | static const size_t npos = ~size_t(0); 29 | 30 | template 31 | StringView(const char (&Str)[N]) : First(Str), Last(Str + N - 1) {} 32 | StringView(const char *First_, const char *Last_) 33 | : First(First_), Last(Last_) {} 34 | StringView(const char *First_, size_t Len) 35 | : First(First_), Last(First_ + Len) {} 36 | StringView(const char *Str) : First(Str), Last(Str + std::strlen(Str)) {} 37 | StringView() : First(nullptr), Last(nullptr) {} 38 | 39 | StringView substr(size_t From) const { 40 | return StringView(begin() + From, size() - From); 41 | } 42 | 43 | size_t find(char C, size_t From = 0) const { 44 | size_t FindBegin = std::min(From, size()); 45 | // Avoid calling memchr with nullptr. 46 | if (FindBegin < size()) { 47 | // Just forward to memchr, which is faster than a hand-rolled loop. 48 | if (const void *P = ::memchr(First + FindBegin, C, size() - FindBegin)) 49 | return size_t(static_cast(P) - First); 50 | } 51 | return npos; 52 | } 53 | 54 | StringView substr(size_t From, size_t To) const { 55 | if (To >= size()) 56 | To = size() - 1; 57 | if (From >= size()) 58 | From = size() - 1; 59 | return StringView(First + From, First + To); 60 | } 61 | 62 | StringView dropFront(size_t N = 1) const { 63 | if (N >= size()) 64 | N = size(); 65 | return StringView(First + N, Last); 66 | } 67 | 68 | StringView dropBack(size_t N = 1) const { 69 | if (N >= size()) 70 | N = size(); 71 | return StringView(First, Last - N); 72 | } 73 | 74 | char front() const { 75 | assert(!empty()); 76 | return *begin(); 77 | } 78 | 79 | char back() const { 80 | assert(!empty()); 81 | return *(end() - 1); 82 | } 83 | 84 | char popFront() { 85 | assert(!empty()); 86 | return *First++; 87 | } 88 | 89 | bool consumeFront(char C) { 90 | if (!startsWith(C)) 91 | return false; 92 | *this = dropFront(1); 93 | return true; 94 | } 95 | 96 | bool consumeFront(StringView S) { 97 | if (!startsWith(S)) 98 | return false; 99 | *this = dropFront(S.size()); 100 | return true; 101 | } 102 | 103 | bool startsWith(char C) const { return !empty() && *begin() == C; } 104 | 105 | bool startsWith(StringView Str) const { 106 | if (Str.size() > size()) 107 | return false; 108 | return std::equal(Str.begin(), Str.end(), begin()); 109 | } 110 | 111 | const char &operator[](size_t Idx) const { return *(begin() + Idx); } 112 | 113 | const char *begin() const { return First; } 114 | const char *end() const { return Last; } 115 | size_t size() const { return static_cast(Last - First); } 116 | bool empty() const { return First == Last; } 117 | }; 118 | 119 | inline bool operator==(const StringView &LHS, const StringView &RHS) { 120 | return LHS.size() == RHS.size() && 121 | std::equal(LHS.begin(), LHS.end(), RHS.begin()); 122 | } 123 | 124 | DEMANGLE_NAMESPACE_END 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /src/demangle/Utility.h: -------------------------------------------------------------------------------- 1 | //===--- Utility.h ----------------------------------------------*- C++ -*-===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // Provide some utility classes for use in the demangler(s). 10 | // 11 | //===----------------------------------------------------------------------===// 12 | 13 | #ifndef DEMANGLE_UTILITY_H 14 | #define DEMANGLE_UTILITY_H 15 | 16 | #include "StringView.h" 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | DEMANGLE_NAMESPACE_BEGIN 24 | 25 | // Stream that AST nodes write their string representation into after the AST 26 | // has been parsed. 27 | class OutputStream { 28 | char *Buffer; 29 | size_t CurrentPosition; 30 | size_t BufferCapacity; 31 | 32 | // Ensure there is at least n more positions in buffer. 33 | void grow(size_t N) { 34 | if (N + CurrentPosition >= BufferCapacity) { 35 | BufferCapacity *= 2; 36 | if (BufferCapacity < N + CurrentPosition) 37 | BufferCapacity = N + CurrentPosition; 38 | Buffer = static_cast(std::realloc(Buffer, BufferCapacity)); 39 | if (Buffer == nullptr) 40 | std::terminate(); 41 | } 42 | } 43 | 44 | void writeUnsigned(uint64_t N, bool isNeg = false) { 45 | // Handle special case... 46 | if (N == 0) { 47 | *this << '0'; 48 | return; 49 | } 50 | 51 | char Temp[21]; 52 | char *TempPtr = std::end(Temp); 53 | 54 | while (N) { 55 | *--TempPtr = '0' + char(N % 10); 56 | N /= 10; 57 | } 58 | 59 | // Add negative sign... 60 | if (isNeg) 61 | *--TempPtr = '-'; 62 | this->operator<<(StringView(TempPtr, std::end(Temp))); 63 | } 64 | 65 | public: 66 | OutputStream(char *StartBuf, size_t Size) 67 | : Buffer(StartBuf), CurrentPosition(0), BufferCapacity(Size) {} 68 | OutputStream() = default; 69 | void reset(char *Buffer_, size_t BufferCapacity_) { 70 | CurrentPosition = 0; 71 | Buffer = Buffer_; 72 | BufferCapacity = BufferCapacity_; 73 | } 74 | 75 | /// If a ParameterPackExpansion (or similar type) is encountered, the offset 76 | /// into the pack that we're currently printing. 77 | unsigned CurrentPackIndex = std::numeric_limits::max(); 78 | unsigned CurrentPackMax = std::numeric_limits::max(); 79 | 80 | OutputStream &operator+=(StringView R) { 81 | size_t Size = R.size(); 82 | if (Size == 0) 83 | return *this; 84 | grow(Size); 85 | std::memmove(Buffer + CurrentPosition, R.begin(), Size); 86 | CurrentPosition += Size; 87 | return *this; 88 | } 89 | 90 | OutputStream &operator+=(char C) { 91 | grow(1); 92 | Buffer[CurrentPosition++] = C; 93 | return *this; 94 | } 95 | 96 | OutputStream &operator<<(StringView R) { return (*this += R); } 97 | 98 | OutputStream &operator<<(char C) { return (*this += C); } 99 | 100 | OutputStream &operator<<(long long N) { 101 | if (N < 0) 102 | writeUnsigned(static_cast(-N), true); 103 | else 104 | writeUnsigned(static_cast(N)); 105 | return *this; 106 | } 107 | 108 | OutputStream &operator<<(unsigned long long N) { 109 | writeUnsigned(N, false); 110 | return *this; 111 | } 112 | 113 | OutputStream &operator<<(long N) { 114 | return this->operator<<(static_cast(N)); 115 | } 116 | 117 | OutputStream &operator<<(unsigned long N) { 118 | return this->operator<<(static_cast(N)); 119 | } 120 | 121 | OutputStream &operator<<(int N) { 122 | return this->operator<<(static_cast(N)); 123 | } 124 | 125 | OutputStream &operator<<(unsigned int N) { 126 | return this->operator<<(static_cast(N)); 127 | } 128 | 129 | size_t getCurrentPosition() const { return CurrentPosition; } 130 | void setCurrentPosition(size_t NewPos) { CurrentPosition = NewPos; } 131 | 132 | char back() const { 133 | return CurrentPosition ? Buffer[CurrentPosition - 1] : '\0'; 134 | } 135 | 136 | bool empty() const { return CurrentPosition == 0; } 137 | 138 | char *getBuffer() { return Buffer; } 139 | char *getBufferEnd() { return Buffer + CurrentPosition - 1; } 140 | size_t getBufferCapacity() { return BufferCapacity; } 141 | }; 142 | 143 | template class SwapAndRestore { 144 | T &Restore; 145 | T OriginalValue; 146 | bool ShouldRestore = true; 147 | 148 | public: 149 | SwapAndRestore(T &Restore_) : SwapAndRestore(Restore_, Restore_) {} 150 | 151 | SwapAndRestore(T &Restore_, T NewVal) 152 | : Restore(Restore_), OriginalValue(Restore) { 153 | Restore = std::move(NewVal); 154 | } 155 | ~SwapAndRestore() { 156 | if (ShouldRestore) 157 | Restore = std::move(OriginalValue); 158 | } 159 | 160 | void shouldRestore(bool ShouldRestore_) { ShouldRestore = ShouldRestore_; } 161 | 162 | void restoreNow(bool Force) { 163 | if (!Force && !ShouldRestore) 164 | return; 165 | 166 | Restore = std::move(OriginalValue); 167 | ShouldRestore = false; 168 | } 169 | 170 | SwapAndRestore(const SwapAndRestore &) = delete; 171 | SwapAndRestore &operator=(const SwapAndRestore &) = delete; 172 | }; 173 | 174 | inline bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, 175 | size_t InitSize) { 176 | size_t BufferSize; 177 | if (Buf == nullptr) { 178 | Buf = static_cast(std::malloc(InitSize)); 179 | if (Buf == nullptr) 180 | return false; 181 | BufferSize = InitSize; 182 | } else 183 | BufferSize = *N; 184 | 185 | S.reset(Buf, BufferSize); 186 | return true; 187 | } 188 | 189 | DEMANGLE_NAMESPACE_END 190 | 191 | #endif 192 | -------------------------------------------------------------------------------- /src/demangle/cp-to-llvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copies the 'demangle' library, excluding 'DemangleConfig.h', to llvm. If no 4 | # llvm directory is specified, then assume a monorepo layout. 5 | 6 | set -e 7 | 8 | FILES="ItaniumDemangle.h StringView.h Utility.h README.txt" 9 | LLVM_DEMANGLE_DIR=$1 10 | 11 | if [[ -z "$LLVM_DEMANGLE_DIR" ]]; then 12 | LLVM_DEMANGLE_DIR="../../../llvm/include/llvm/Demangle" 13 | fi 14 | 15 | if [[ ! -d "$LLVM_DEMANGLE_DIR" ]]; then 16 | echo "No such directory: $LLVM_DEMANGLE_DIR" >&2 17 | exit 1 18 | fi 19 | 20 | read -p "This will overwrite the copies of $FILES in $LLVM_DEMANGLE_DIR; are you sure? [y/N]" -n 1 -r ANSWER 21 | echo 22 | 23 | if [[ $ANSWER =~ ^[Yy]$ ]]; then 24 | for I in $FILES ; do 25 | cp $I $LLVM_DEMANGLE_DIR/$I 26 | done 27 | fi 28 | -------------------------------------------------------------------------------- /src/fallback_malloc.h: -------------------------------------------------------------------------------- 1 | //===------------------------- fallback_malloc.h --------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #ifndef _FALLBACK_MALLOC_H 10 | #define _FALLBACK_MALLOC_H 11 | 12 | #include "__cxxabi_config.h" 13 | #include // for size_t 14 | 15 | namespace __cxxabiv1 { 16 | 17 | // Allocate some memory from _somewhere_ 18 | _LIBCXXABI_HIDDEN void * __aligned_malloc_with_fallback(size_t size); 19 | 20 | // Allocate and zero-initialize memory from _somewhere_ 21 | _LIBCXXABI_HIDDEN void * __calloc_with_fallback(size_t count, size_t size); 22 | 23 | _LIBCXXABI_HIDDEN void __aligned_free_with_fallback(void *ptr); 24 | _LIBCXXABI_HIDDEN void __free_with_fallback(void *ptr); 25 | 26 | } // namespace __cxxabiv1 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/include/refstring.h: -------------------------------------------------------------------------------- 1 | //===------------------------ __refstring ---------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // FIXME: This file is copied from libcxx/src/include/refstring.h. Instead of 10 | // duplicating the file in libc++abi we should require that the libc++ sources 11 | // are available when building libc++abi. 12 | 13 | #ifndef _LIBCPPABI_REFSTRING_H 14 | #define _LIBCPPABI_REFSTRING_H 15 | 16 | #include <__config> 17 | #include 18 | #include 19 | #include 20 | #ifdef __APPLE__ 21 | #include 22 | #include 23 | #endif 24 | #include "atomic_support.h" 25 | 26 | _LIBCPP_BEGIN_NAMESPACE_STD 27 | 28 | namespace __refstring_imp { namespace { 29 | typedef int count_t; 30 | 31 | struct _Rep_base { 32 | std::size_t len; 33 | std::size_t cap; 34 | count_t count; 35 | }; 36 | 37 | inline _Rep_base* rep_from_data(const char *data_) noexcept { 38 | char *data = const_cast(data_); 39 | return reinterpret_cast<_Rep_base *>(data - sizeof(_Rep_base)); 40 | } 41 | 42 | inline char * data_from_rep(_Rep_base *rep) noexcept { 43 | char *data = reinterpret_cast(rep); 44 | return data + sizeof(*rep); 45 | } 46 | 47 | #if defined(__APPLE__) 48 | inline 49 | const char* compute_gcc_empty_string_storage() _NOEXCEPT 50 | { 51 | void* handle = dlopen("/usr/lib/libstdc++.6.dylib", RTLD_NOLOAD); 52 | if (handle == nullptr) 53 | return nullptr; 54 | void* sym = dlsym(handle, "_ZNSs4_Rep20_S_empty_rep_storageE"); 55 | if (sym == nullptr) 56 | return nullptr; 57 | return data_from_rep(reinterpret_cast<_Rep_base *>(sym)); 58 | } 59 | 60 | inline 61 | const char* 62 | get_gcc_empty_string_storage() _NOEXCEPT 63 | { 64 | static const char* p = compute_gcc_empty_string_storage(); 65 | return p; 66 | } 67 | #endif 68 | 69 | }} // namespace __refstring_imp 70 | 71 | using namespace __refstring_imp; 72 | 73 | inline 74 | __libcpp_refstring::__libcpp_refstring(const char* msg) { 75 | std::size_t len = strlen(msg); 76 | _Rep_base* rep = static_cast<_Rep_base *>(::operator new(sizeof(*rep) + len + 1)); 77 | rep->len = len; 78 | rep->cap = len; 79 | rep->count = 0; 80 | char *data = data_from_rep(rep); 81 | std::memcpy(data, msg, len + 1); 82 | __imp_ = data; 83 | } 84 | 85 | inline 86 | __libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) _NOEXCEPT 87 | : __imp_(s.__imp_) 88 | { 89 | if (__uses_refcount()) 90 | __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1); 91 | } 92 | 93 | inline 94 | __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) _NOEXCEPT { 95 | bool adjust_old_count = __uses_refcount(); 96 | struct _Rep_base *old_rep = rep_from_data(__imp_); 97 | __imp_ = s.__imp_; 98 | if (__uses_refcount()) 99 | __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1); 100 | if (adjust_old_count) 101 | { 102 | if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0) 103 | { 104 | ::operator delete(old_rep); 105 | } 106 | } 107 | return *this; 108 | } 109 | 110 | inline 111 | __libcpp_refstring::~__libcpp_refstring() { 112 | if (__uses_refcount()) { 113 | _Rep_base* rep = rep_from_data(__imp_); 114 | if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) { 115 | ::operator delete(rep); 116 | } 117 | } 118 | } 119 | 120 | inline 121 | bool __libcpp_refstring::__uses_refcount() const { 122 | #ifdef __APPLE__ 123 | return __imp_ != get_gcc_empty_string_storage(); 124 | #else 125 | return true; 126 | #endif 127 | } 128 | 129 | _LIBCPP_END_NAMESPACE_STD 130 | 131 | #endif //_LIBCPPABI_REFSTRING_H 132 | -------------------------------------------------------------------------------- /src/stdlib_exception.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------------- exception.cpp ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #define _LIBCPP_BUILDING_LIBRARY 10 | #include 11 | #include 12 | 13 | namespace std 14 | { 15 | 16 | // exception 17 | 18 | exception::~exception() _NOEXCEPT 19 | { 20 | } 21 | 22 | const char* exception::what() const _NOEXCEPT 23 | { 24 | return "std::exception"; 25 | } 26 | 27 | // bad_exception 28 | 29 | bad_exception::~bad_exception() _NOEXCEPT 30 | { 31 | } 32 | 33 | const char* bad_exception::what() const _NOEXCEPT 34 | { 35 | return "std::bad_exception"; 36 | } 37 | 38 | 39 | // bad_alloc 40 | 41 | bad_alloc::bad_alloc() _NOEXCEPT 42 | { 43 | } 44 | 45 | bad_alloc::~bad_alloc() _NOEXCEPT 46 | { 47 | } 48 | 49 | const char* 50 | bad_alloc::what() const _NOEXCEPT 51 | { 52 | return "std::bad_alloc"; 53 | } 54 | 55 | // bad_array_new_length 56 | 57 | bad_array_new_length::bad_array_new_length() _NOEXCEPT 58 | { 59 | } 60 | 61 | bad_array_new_length::~bad_array_new_length() _NOEXCEPT 62 | { 63 | } 64 | 65 | const char* 66 | bad_array_new_length::what() const _NOEXCEPT 67 | { 68 | return "bad_array_new_length"; 69 | } 70 | 71 | } // std 72 | -------------------------------------------------------------------------------- /src/stdlib_stdexcept.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------ stdexcept.cpp -------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include "include/refstring.h" 10 | #include "stdexcept" 11 | #include "new" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | static_assert(sizeof(std::__libcpp_refstring) == sizeof(const char *), ""); 18 | 19 | namespace std // purposefully not using versioning namespace 20 | { 21 | 22 | logic_error::~logic_error() _NOEXCEPT {} 23 | 24 | const char* 25 | logic_error::what() const _NOEXCEPT 26 | { 27 | return __imp_.c_str(); 28 | } 29 | 30 | runtime_error::~runtime_error() _NOEXCEPT {} 31 | 32 | const char* 33 | runtime_error::what() const _NOEXCEPT 34 | { 35 | return __imp_.c_str(); 36 | } 37 | 38 | domain_error::~domain_error() _NOEXCEPT {} 39 | invalid_argument::~invalid_argument() _NOEXCEPT {} 40 | length_error::~length_error() _NOEXCEPT {} 41 | out_of_range::~out_of_range() _NOEXCEPT {} 42 | 43 | range_error::~range_error() _NOEXCEPT {} 44 | overflow_error::~overflow_error() _NOEXCEPT {} 45 | underflow_error::~underflow_error() _NOEXCEPT {} 46 | 47 | } // std 48 | -------------------------------------------------------------------------------- /src/stdlib_typeinfo.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------------- typeinfo.cpp ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include 10 | 11 | namespace std 12 | { 13 | 14 | // type_info 15 | 16 | type_info::~type_info() 17 | { 18 | } 19 | 20 | // bad_cast 21 | 22 | bad_cast::bad_cast() _NOEXCEPT 23 | { 24 | } 25 | 26 | bad_cast::~bad_cast() _NOEXCEPT 27 | { 28 | } 29 | 30 | const char* 31 | bad_cast::what() const _NOEXCEPT 32 | { 33 | return "std::bad_cast"; 34 | } 35 | 36 | // bad_typeid 37 | 38 | bad_typeid::bad_typeid() _NOEXCEPT 39 | { 40 | } 41 | 42 | bad_typeid::~bad_typeid() _NOEXCEPT 43 | { 44 | } 45 | 46 | const char* 47 | bad_typeid::what() const _NOEXCEPT 48 | { 49 | return "std::bad_typeid"; 50 | } 51 | 52 | } // std 53 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include(AddLLVM) # for add_lit_testsuite 2 | macro(pythonize_bool var) 3 | if (${var}) 4 | set(${var} True) 5 | else() 6 | set(${var} False) 7 | endif() 8 | endmacro() 9 | 10 | if (NOT DEFINED LIBCXX_ENABLE_SHARED) 11 | set(LIBCXX_ENABLE_SHARED ON) 12 | endif() 13 | 14 | pythonize_bool(LIBCXXABI_BUILD_32_BITS) 15 | pythonize_bool(LIBCXX_ENABLE_SHARED) 16 | pythonize_bool(LIBCXXABI_ENABLE_SHARED) 17 | pythonize_bool(LIBCXXABI_ENABLE_THREADS) 18 | pythonize_bool(LIBCXXABI_ENABLE_EXCEPTIONS) 19 | pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER) 20 | pythonize_bool(LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY) 21 | set(LIBCXXABI_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING 22 | "TargetInfo to use when setting up test environment.") 23 | set(LIBCXXABI_EXECUTOR "None" CACHE STRING 24 | "Executor to use when running tests.") 25 | 26 | set(AUTO_GEN_COMMENT "## Autogenerated by libcxxabi configuration.\n# Do not edit!") 27 | 28 | if (LIBCXXABI_ENABLE_SHARED) 29 | set(LIBCXXABI_TEST_DEPS cxxabi_shared) 30 | else() 31 | set(LIBCXXABI_TEST_DEPS cxxabi_static) 32 | endif() 33 | 34 | if (LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY) 35 | list(APPEND LIBCXXABI_TEST_DEPS cxx_external_threads) 36 | endif() 37 | 38 | if (NOT LIBCXXABI_STANDALONE_BUILD) 39 | list(APPEND LIBCXXABI_TEST_DEPS cxx) 40 | if (LIBCXXABI_USE_LLVM_UNWINDER) 41 | list(APPEND LIBCXXABI_TEST_DEPS unwind) 42 | endif() 43 | endif() 44 | 45 | 46 | configure_lit_site_cfg( 47 | ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in 48 | ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg) 49 | 50 | add_lit_testsuite(check-cxxabi "Running libcxxabi tests" 51 | ${CMAKE_CURRENT_BINARY_DIR} 52 | DEPENDS ${LIBCXXABI_TEST_DEPS} 53 | ) 54 | 55 | # TODO: This is a legacy target name and should be removed at some point. 56 | add_custom_target(check-libcxxabi DEPENDS check-cxxabi) 57 | -------------------------------------------------------------------------------- /test/backtrace_test.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- backtrace_test.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | extern "C" _Unwind_Reason_Code 16 | trace_function(struct _Unwind_Context*, void* ntraced) { 17 | (*reinterpret_cast(ntraced))++; 18 | // We should never have a call stack this deep... 19 | assert(*reinterpret_cast(ntraced) < 20); 20 | return _URC_NO_REASON; 21 | } 22 | 23 | __attribute__ ((__noinline__)) 24 | void call3_throw(size_t* ntraced) { 25 | try { 26 | _Unwind_Backtrace(trace_function, ntraced); 27 | } catch (...) { 28 | assert(false); 29 | } 30 | } 31 | 32 | __attribute__ ((__noinline__, __disable_tail_calls__)) 33 | void call3_nothrow(size_t* ntraced) { 34 | _Unwind_Backtrace(trace_function, ntraced); 35 | } 36 | 37 | __attribute__ ((__noinline__, __disable_tail_calls__)) 38 | void call2(size_t* ntraced, bool do_throw) { 39 | if (do_throw) { 40 | call3_throw(ntraced); 41 | } else { 42 | call3_nothrow(ntraced); 43 | } 44 | } 45 | 46 | __attribute__ ((__noinline__, __disable_tail_calls__)) 47 | void call1(size_t* ntraced, bool do_throw) { 48 | call2(ntraced, do_throw); 49 | } 50 | 51 | int main() { 52 | size_t throw_ntraced = 0; 53 | size_t nothrow_ntraced = 0; 54 | 55 | call1(¬hrow_ntraced, false); 56 | 57 | try { 58 | call1(&throw_ntraced, true); 59 | } catch (...) { 60 | assert(false); 61 | } 62 | 63 | // Different platforms (and different runtimes) will unwind a different number 64 | // of times, so we can't make any better assumptions than this. 65 | assert(nothrow_ntraced > 1); 66 | assert(throw_ntraced == nothrow_ntraced); // Make sure we unwind through catch 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /test/catch_array_01.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_array_01.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // Can you have a catch clause of array type that catches anything? 10 | 11 | // GCC incorrectly allows array types to be caught by reference. 12 | // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69372 13 | // XFAIL: gcc 14 | // UNSUPPORTED: libcxxabi-no-exceptions 15 | 16 | #include 17 | 18 | int main() 19 | { 20 | typedef char Array[4]; 21 | Array a = {'H', 'i', '!', 0}; 22 | try 23 | { 24 | throw a; // converts to char* 25 | assert(false); 26 | } 27 | catch (Array& b) // can't catch char* 28 | { 29 | assert(false); 30 | } 31 | catch (...) 32 | { 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/catch_array_02.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_array_02.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // Can you have a catch clause of array type that catches anything? 10 | // UNSUPPORTED: libcxxabi-no-exceptions 11 | 12 | #include 13 | 14 | int main() 15 | { 16 | typedef char Array[4]; 17 | Array a = {'H', 'i', '!', 0}; 18 | try 19 | { 20 | throw a; // converts to char* 21 | assert(false); 22 | } 23 | catch (Array b) // equivalent to char* 24 | { 25 | } 26 | catch (...) 27 | { 28 | assert(false); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/catch_class_01.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_class_01.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | struct A 16 | { 17 | static int count; 18 | int id_; 19 | explicit A(int id) : id_(id) {count++;} 20 | A(const A& a) : id_(a.id_) {count++;} 21 | ~A() {count--;} 22 | }; 23 | 24 | int A::count = 0; 25 | 26 | void f1() 27 | { 28 | throw A(3); 29 | } 30 | 31 | void f2() 32 | { 33 | try 34 | { 35 | assert(A::count == 0); 36 | f1(); 37 | } 38 | catch (A a) 39 | { 40 | assert(A::count != 0); 41 | assert(a.id_ == 3); 42 | throw; 43 | } 44 | } 45 | 46 | int main() 47 | { 48 | try 49 | { 50 | f2(); 51 | assert(false); 52 | } 53 | catch (const A& a) 54 | { 55 | assert(A::count != 0); 56 | assert(a.id_ == 3); 57 | } 58 | assert(A::count == 0); 59 | } 60 | -------------------------------------------------------------------------------- /test/catch_class_02.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_class_02.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | struct B 16 | { 17 | static int count; 18 | int id_; 19 | explicit B(int id) : id_(id) {count++;} 20 | B(const B& a) : id_(a.id_) {count++;} 21 | ~B() {count--;} 22 | }; 23 | 24 | int B::count = 0; 25 | 26 | struct A 27 | : B 28 | { 29 | static int count; 30 | int id_; 31 | explicit A(int id) : B(id-1), id_(id) {count++;} 32 | A(const A& a) : B(a.id_-1), id_(a.id_) {count++;} 33 | ~A() {count--;} 34 | }; 35 | 36 | int A::count = 0; 37 | 38 | void f1() 39 | { 40 | assert(A::count == 0); 41 | assert(B::count == 0); 42 | A a(3); 43 | assert(A::count == 1); 44 | assert(B::count == 1); 45 | throw a; 46 | assert(false); 47 | } 48 | 49 | void f2() 50 | { 51 | try 52 | { 53 | assert(A::count == 0); 54 | f1(); 55 | assert(false); 56 | } 57 | catch (A a) 58 | { 59 | assert(A::count != 0); 60 | assert(B::count != 0); 61 | assert(a.id_ == 3); 62 | throw; 63 | } 64 | catch (B b) 65 | { 66 | assert(false); 67 | } 68 | } 69 | 70 | int main() 71 | { 72 | try 73 | { 74 | f2(); 75 | assert(false); 76 | } 77 | catch (const B& b) 78 | { 79 | assert(B::count != 0); 80 | assert(b.id_ == 2); 81 | } 82 | assert(A::count == 0); 83 | assert(B::count == 0); 84 | } 85 | -------------------------------------------------------------------------------- /test/catch_class_03.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_class_03.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | /* 10 | This test checks that adjustedPtr is correct as there exist offsets in this 11 | object for the various subobjects, all of which have a unique id_ to 12 | check against. 13 | */ 14 | 15 | // UNSUPPORTED: libcxxabi-no-exceptions 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | // Clang emits warnings about exceptions of type 'Child' being caught by 22 | // an earlier handler of type 'Base'. Congrats clang, you've just 23 | // diagnosed the behavior under test. 24 | #if defined(__clang__) 25 | #pragma clang diagnostic ignored "-Wexceptions" 26 | #endif 27 | 28 | struct B 29 | { 30 | static int count; 31 | int id_; 32 | explicit B(int id) : id_(id) {count++;} 33 | B(const B& a) : id_(a.id_) {count++;} 34 | ~B() {count--;} 35 | }; 36 | 37 | int B::count = 0; 38 | 39 | struct C1 40 | : B 41 | { 42 | static int count; 43 | int id_; 44 | explicit C1(int id) : B(id-2), id_(id) {count++;} 45 | C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;} 46 | ~C1() {count--;} 47 | }; 48 | 49 | int C1::count = 0; 50 | 51 | struct C2 52 | : B 53 | { 54 | static int count; 55 | int id_; 56 | explicit C2(int id) : B(id-2), id_(id) {count++;} 57 | C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;} 58 | ~C2() {count--;} 59 | }; 60 | 61 | int C2::count = 0; 62 | 63 | struct A 64 | : C1, C2 65 | { 66 | static int count; 67 | int id_; 68 | explicit A(int id) : C1(id-1), C2(id-2), id_(id) {count++;} 69 | A(const A& a) : C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;} 70 | ~A() {count--;} 71 | }; 72 | 73 | int A::count = 0; 74 | 75 | void f1() 76 | { 77 | assert(A::count == 0); 78 | assert(C1::count == 0); 79 | assert(C2::count == 0); 80 | assert(B::count == 0); 81 | A a(5); 82 | assert(A::count == 1); 83 | assert(C1::count == 1); 84 | assert(C2::count == 1); 85 | assert(B::count == 2); 86 | 87 | assert(a.id_ == 5); 88 | assert(static_cast(a).id_ == 4); 89 | assert(static_cast(a).id_ == 3); 90 | assert(static_cast(static_cast(a)).id_ == 2); 91 | assert(static_cast(static_cast(a)).id_ == 1); 92 | throw a; 93 | assert(false); 94 | } 95 | 96 | void f2() 97 | { 98 | try 99 | { 100 | assert(A::count == 0); 101 | assert(C1::count == 0); 102 | assert(C2::count == 0); 103 | assert(B::count == 0); 104 | f1(); 105 | assert(false); 106 | } 107 | catch (const A& a) // can catch A 108 | { 109 | assert(a.id_ == 5); 110 | assert(static_cast(a).id_ == 4); 111 | assert(static_cast(a).id_ == 3); 112 | assert(static_cast(static_cast(a)).id_ == 2); 113 | assert(static_cast(static_cast(a)).id_ == 1); 114 | throw; 115 | } 116 | catch (const C1&) 117 | { 118 | assert(false); 119 | } 120 | catch (const C2&) 121 | { 122 | assert(false); 123 | } 124 | catch (const B&) 125 | { 126 | assert(false); 127 | } 128 | } 129 | 130 | void f3() 131 | { 132 | try 133 | { 134 | assert(A::count == 0); 135 | assert(C1::count == 0); 136 | assert(C2::count == 0); 137 | assert(B::count == 0); 138 | f2(); 139 | assert(false); 140 | } 141 | catch (const B& a) // can not catch B (ambiguous base) 142 | { 143 | assert(false); 144 | } 145 | catch (const C1& c1) // can catch C1 146 | { 147 | assert(c1.id_ == 4); 148 | assert(static_cast(c1).id_ == 2); 149 | throw; 150 | } 151 | catch (const C2&) 152 | { 153 | assert(false); 154 | } 155 | } 156 | 157 | void f4() 158 | { 159 | try 160 | { 161 | assert(A::count == 0); 162 | assert(C1::count == 0); 163 | assert(C2::count == 0); 164 | assert(B::count == 0); 165 | f3(); 166 | assert(false); 167 | } 168 | catch (const B& a) // can not catch B (ambiguous base) 169 | { 170 | assert(false); 171 | } 172 | catch (const C2& c2) // can catch C2 173 | { 174 | assert(c2.id_ == 3); 175 | assert(static_cast(c2).id_ == 1); 176 | throw; 177 | } 178 | catch (const C1&) 179 | { 180 | assert(false); 181 | } 182 | } 183 | 184 | int main() 185 | { 186 | try 187 | { 188 | f4(); 189 | assert(false); 190 | } 191 | catch (...) 192 | { 193 | } 194 | assert(A::count == 0); 195 | assert(C1::count == 0); 196 | assert(C2::count == 0); 197 | assert(B::count == 0); 198 | } 199 | -------------------------------------------------------------------------------- /test/catch_class_04.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_class_04.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | /* 10 | This test checks that adjustedPtr is correct as there exist offsets in this 11 | object for the various subobjects, all of which have a unique id_ to 12 | check against. It also checks that virtual bases work properly 13 | */ 14 | 15 | // UNSUPPORTED: libcxxabi-no-exceptions 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | // Clang emits warnings about exceptions of type 'Child' being caught by 22 | // an earlier handler of type 'Base'. Congrats clang, you've just 23 | // diagnosed the behavior under test. 24 | #if defined(__clang__) 25 | #pragma clang diagnostic ignored "-Wexceptions" 26 | #endif 27 | 28 | struct B 29 | { 30 | static int count; 31 | int id_; 32 | explicit B(int id) : id_(id) {count++;} 33 | B(const B& a) : id_(a.id_) {count++;} 34 | ~B() {count--;} 35 | }; 36 | 37 | int B::count = 0; 38 | 39 | struct C1 40 | : virtual B 41 | { 42 | static int count; 43 | int id_; 44 | explicit C1(int id) : B(id-2), id_(id) {count++;} 45 | C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;} 46 | ~C1() {count--;} 47 | }; 48 | 49 | int C1::count = 0; 50 | 51 | struct C2 52 | : virtual private B 53 | { 54 | static int count; 55 | int id_; 56 | explicit C2(int id) : B(id-2), id_(id) {count++;} 57 | C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;} 58 | ~C2() {count--;} 59 | }; 60 | 61 | int C2::count = 0; 62 | 63 | struct A 64 | : C1, C2 65 | { 66 | static int count; 67 | int id_; 68 | explicit A(int id) : B(id+3), C1(id-1), C2(id-2), id_(id) {count++;} 69 | A(const A& a) : B(a.id_+3), C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;} 70 | ~A() {count--;} 71 | }; 72 | 73 | int A::count = 0; 74 | 75 | void f1() 76 | { 77 | assert(A::count == 0); 78 | assert(C1::count == 0); 79 | assert(C2::count == 0); 80 | assert(B::count == 0); 81 | A a(5); 82 | assert(A::count == 1); 83 | assert(C1::count == 1); 84 | assert(C2::count == 1); 85 | assert(B::count == 1); 86 | 87 | assert(a.id_ == 5); 88 | assert(static_cast(a).id_ == 4); 89 | assert(static_cast(a).id_ == 3); 90 | assert(static_cast(a).id_ == 8); 91 | throw a; 92 | assert(false); 93 | } 94 | 95 | void f2() 96 | { 97 | try 98 | { 99 | assert(A::count == 0); 100 | assert(C1::count == 0); 101 | assert(C2::count == 0); 102 | assert(B::count == 0); 103 | f1(); 104 | assert(false); 105 | } 106 | catch (const A& a) // can catch A 107 | { 108 | assert(a.id_ == 5); 109 | assert(static_cast(a).id_ == 4); 110 | assert(static_cast(a).id_ == 3); 111 | assert(static_cast(a).id_ == 8); 112 | throw; 113 | } 114 | catch (const C1&) 115 | { 116 | assert(false); 117 | } 118 | catch (const C2&) 119 | { 120 | assert(false); 121 | } 122 | catch (const B&) 123 | { 124 | assert(false); 125 | } 126 | } 127 | 128 | void f3() 129 | { 130 | try 131 | { 132 | assert(A::count == 0); 133 | assert(C1::count == 0); 134 | assert(C2::count == 0); 135 | assert(B::count == 0); 136 | f2(); 137 | assert(false); 138 | } 139 | catch (const B& a) // can catch B 140 | { 141 | assert(static_cast(a).id_ == 8); 142 | throw; 143 | } 144 | catch (const C1& c1) 145 | { 146 | assert(false); 147 | } 148 | catch (const C2&) 149 | { 150 | assert(false); 151 | } 152 | } 153 | 154 | void f4() 155 | { 156 | try 157 | { 158 | assert(A::count == 0); 159 | assert(C1::count == 0); 160 | assert(C2::count == 0); 161 | assert(B::count == 0); 162 | f3(); 163 | assert(false); 164 | } 165 | catch (const C2& c2) // can catch C2 166 | { 167 | assert(c2.id_ == 3); 168 | throw; 169 | } 170 | catch (const B& a) // can not catch B (ambiguous base) 171 | { 172 | assert(false); 173 | } 174 | catch (const C1&) 175 | { 176 | assert(false); 177 | } 178 | } 179 | 180 | void f5() 181 | { 182 | try 183 | { 184 | assert(A::count == 0); 185 | assert(C1::count == 0); 186 | assert(C2::count == 0); 187 | assert(B::count == 0); 188 | f4(); 189 | assert(false); 190 | } 191 | catch (const C1& c1) // can catch C1 192 | { 193 | assert(c1.id_ == 4); 194 | assert(static_cast(c1).id_ == 8); 195 | throw; 196 | } 197 | catch (const B& a) 198 | { 199 | assert(false); 200 | } 201 | catch (const C2&) 202 | { 203 | assert(false); 204 | } 205 | } 206 | 207 | int main() 208 | { 209 | try 210 | { 211 | f5(); 212 | assert(false); 213 | } 214 | catch (...) 215 | { 216 | } 217 | assert(A::count == 0); 218 | assert(C1::count == 0); 219 | assert(C2::count == 0); 220 | assert(B::count == 0); 221 | } 222 | -------------------------------------------------------------------------------- /test/catch_const_pointer_nullptr.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------- catch_const_pointer_nullptr.cpp ----------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | 13 | // Clang emits warnings about exceptions of type 'Child' being caught by 14 | // an earlier handler of type 'Base'. Congrats clang, you've just 15 | // diagnosed the behavior under test. 16 | #if defined(__clang__) 17 | #pragma clang diagnostic ignored "-Wexceptions" 18 | #endif 19 | 20 | #if __has_feature(cxx_nullptr) 21 | 22 | struct A {}; 23 | 24 | void test1() 25 | { 26 | try 27 | { 28 | throw nullptr; 29 | assert(false); 30 | } 31 | catch (A* p) 32 | { 33 | assert(!p); 34 | } 35 | catch (const A*) 36 | { 37 | assert(false); 38 | } 39 | } 40 | 41 | 42 | void test2() 43 | { 44 | try 45 | { 46 | throw nullptr; 47 | assert(false); 48 | } 49 | catch (const A* p) 50 | { 51 | assert(!p); 52 | } 53 | catch (A*) 54 | { 55 | assert(false); 56 | } 57 | } 58 | 59 | void test3() 60 | { 61 | try 62 | { 63 | throw nullptr; 64 | assert(false); 65 | } 66 | catch (const A* const p) 67 | { 68 | assert(!p); 69 | } 70 | catch (A*) 71 | { 72 | assert(false); 73 | } 74 | } 75 | 76 | void test4() 77 | { 78 | try 79 | { 80 | throw nullptr; 81 | assert(false); 82 | } 83 | catch (A* p) 84 | { 85 | assert(!p); 86 | } 87 | catch (const A* const) 88 | { 89 | assert(false); 90 | } 91 | } 92 | 93 | void test5() 94 | { 95 | try 96 | { 97 | throw nullptr; 98 | assert(false); 99 | } 100 | catch (A const* p) 101 | { 102 | assert(!p); 103 | } 104 | catch (A*) 105 | { 106 | assert(false); 107 | } 108 | } 109 | 110 | void test6() 111 | { 112 | try 113 | { 114 | throw nullptr; 115 | assert(false); 116 | } 117 | catch (A* p) 118 | { 119 | assert(!p); 120 | } 121 | catch (A const*) 122 | { 123 | assert(false); 124 | } 125 | } 126 | 127 | 128 | #else 129 | 130 | void test1() {} 131 | void test2() {} 132 | void test3() {} 133 | void test4() {} 134 | void test5() {} 135 | void test6() {} 136 | 137 | #endif 138 | 139 | int main() 140 | { 141 | test1(); 142 | test2(); 143 | test3(); 144 | test4(); 145 | test5(); 146 | test6(); 147 | } 148 | -------------------------------------------------------------------------------- /test/catch_function_01.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- catch_function_01.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // Can you have a catch clause of array type that catches anything? 10 | 11 | // GCC incorrectly allows function pointer to be caught by reference. 12 | // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69372 13 | // XFAIL: gcc 14 | // UNSUPPORTED: libcxxabi-no-exceptions 15 | 16 | #include 17 | 18 | template 19 | bool can_convert(Tp) { return true; } 20 | 21 | template 22 | bool can_convert(...) { return false; } 23 | 24 | void f() {} 25 | 26 | int main() 27 | { 28 | typedef void Function(); 29 | assert(!can_convert(&f)); 30 | assert(!can_convert(&f)); 31 | try 32 | { 33 | throw f; // converts to void (*)() 34 | assert(false); 35 | } 36 | catch (Function& b) // can't catch void (*)() 37 | { 38 | assert(false); 39 | } 40 | catch (void*) // can't catch as void* 41 | { 42 | assert(false); 43 | } 44 | catch(Function*) 45 | { 46 | } 47 | catch (...) 48 | { 49 | assert(false); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /test/catch_function_02.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_function_02.cpp -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // Can you have a catch clause of array type that catches anything? 10 | // UNSUPPORTED: libcxxabi-no-exceptions 11 | 12 | #include 13 | 14 | void f() {} 15 | 16 | int main() 17 | { 18 | typedef void Function(); 19 | try 20 | { 21 | throw f; // converts to void (*)() 22 | assert(false); 23 | } 24 | catch (Function b) // equivalent to void (*)() 25 | { 26 | } 27 | catch (...) 28 | { 29 | assert(false); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/catch_function_03.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_function_03.cpp -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // Can a noexcept function pointer be caught by a non-noexcept catch clause? 10 | // UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-noexcept-function-type 11 | 12 | #include 13 | 14 | template void f() noexcept(Noexcept) {} 15 | template using FnType = void() noexcept(Noexcept); 16 | 17 | template 18 | void check() 19 | { 20 | try 21 | { 22 | auto *p = f; 23 | throw p; 24 | assert(false); 25 | } 26 | catch (FnType *p) 27 | { 28 | assert(ThrowNoexcept || !CatchNoexcept); 29 | assert(p == &f); 30 | } 31 | catch (...) 32 | { 33 | assert(!ThrowNoexcept && CatchNoexcept); 34 | } 35 | } 36 | 37 | void check_deep() { 38 | auto *p = f; 39 | try 40 | { 41 | throw &p; 42 | } 43 | catch (FnType **q) 44 | { 45 | assert(false); 46 | } 47 | catch (FnType **q) 48 | { 49 | } 50 | catch (...) 51 | { 52 | assert(false); 53 | } 54 | } 55 | 56 | int main() 57 | { 58 | check(); 59 | check(); 60 | check(); 61 | check(); 62 | check_deep(); 63 | } 64 | -------------------------------------------------------------------------------- /test/catch_in_noexcept.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_in_noexcept.cpp--------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | struct A {}; 16 | 17 | // Despite being marked as noexcept, this function must have an EHT entry that 18 | // is not 'cantunwind', so that the unwinder can correctly deal with the throw. 19 | void f1() noexcept 20 | { 21 | try { 22 | A a; 23 | throw a; 24 | assert(false); 25 | } catch (...) { 26 | assert(true); 27 | return; 28 | } 29 | assert(false); 30 | } 31 | 32 | int main() 33 | { 34 | f1(); 35 | } 36 | -------------------------------------------------------------------------------- /test/catch_member_data_pointer_01.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------- catch_member_data_pointer_01.cpp -------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | 13 | struct A 14 | { 15 | A() : i(0), j(0) {} // explicitly initialize 'i' to prevent warnings 16 | const int i; 17 | int j; 18 | }; 19 | 20 | typedef const int A::*md1; 21 | typedef int A::*md2; 22 | 23 | struct B : public A 24 | { 25 | B() : k(0), l(0) {} // explicitly initialize 'k' to prevent warnings. 26 | const int k; 27 | int l; 28 | }; 29 | 30 | typedef const int B::*der1; 31 | typedef int B::*der2; 32 | 33 | void test1() 34 | { 35 | try 36 | { 37 | throw &A::i; 38 | assert(false); 39 | } 40 | catch (md2) 41 | { 42 | assert(false); 43 | } 44 | catch (md1) 45 | { 46 | } 47 | } 48 | 49 | // Check that cv qualified conversions are allowed. 50 | void test2() 51 | { 52 | try 53 | { 54 | throw &A::j; 55 | } 56 | catch (md2) 57 | { 58 | } 59 | catch (...) 60 | { 61 | assert(false); 62 | } 63 | 64 | try 65 | { 66 | throw &A::j; 67 | assert(false); 68 | } 69 | catch (md1) 70 | { 71 | } 72 | catch (...) 73 | { 74 | assert(false); 75 | } 76 | } 77 | 78 | // Check that Base -> Derived conversions are NOT allowed. 79 | void test3() 80 | { 81 | try 82 | { 83 | throw &A::i; 84 | assert(false); 85 | } 86 | catch (md2) 87 | { 88 | assert(false); 89 | } 90 | catch (der2) 91 | { 92 | assert(false); 93 | } 94 | catch (der1) 95 | { 96 | assert(false); 97 | } 98 | catch (md1) 99 | { 100 | } 101 | } 102 | 103 | // Check that Base -> Derived conversions NOT are allowed with different cv 104 | // qualifiers. 105 | void test4() 106 | { 107 | try 108 | { 109 | throw &A::j; 110 | assert(false); 111 | } 112 | catch (der2) 113 | { 114 | assert(false); 115 | } 116 | catch (der1) 117 | { 118 | assert(false); 119 | } 120 | catch (md2) 121 | { 122 | } 123 | catch (...) 124 | { 125 | assert(false); 126 | } 127 | } 128 | 129 | // Check that no Derived -> Base conversions are allowed. 130 | void test5() 131 | { 132 | try 133 | { 134 | throw &B::k; 135 | assert(false); 136 | } 137 | catch (md1) 138 | { 139 | assert(false); 140 | } 141 | catch (md2) 142 | { 143 | assert(false); 144 | } 145 | catch (der1) 146 | { 147 | } 148 | 149 | try 150 | { 151 | throw &B::l; 152 | assert(false); 153 | } 154 | catch (md1) 155 | { 156 | assert(false); 157 | } 158 | catch (md2) 159 | { 160 | assert(false); 161 | } 162 | catch (der2) 163 | { 164 | } 165 | } 166 | 167 | int main() 168 | { 169 | test1(); 170 | test2(); 171 | test3(); 172 | test4(); 173 | test5(); 174 | } 175 | -------------------------------------------------------------------------------- /test/catch_member_function_pointer_01.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------- catch_member_function_pointer_01.cpp -----------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // GCC incorrectly allows PMF type "void (T::*)()" to be caught as "void (T::*)() const" 10 | // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69375 11 | // XFAIL: gcc 12 | // UNSUPPORTED: libcxxabi-no-exceptions 13 | #include 14 | 15 | struct A 16 | { 17 | void foo() {} 18 | void bar() const {} 19 | }; 20 | 21 | typedef void (A::*mf1)(); 22 | typedef void (A::*mf2)() const; 23 | 24 | struct B : public A 25 | { 26 | }; 27 | 28 | typedef void (B::*dmf1)(); 29 | typedef void (B::*dmf2)() const; 30 | 31 | template 32 | bool can_convert(Tp) { return true; } 33 | 34 | template 35 | bool can_convert(...) { return false; } 36 | 37 | 38 | void test1() 39 | { 40 | try 41 | { 42 | throw &A::foo; 43 | assert(false); 44 | } 45 | catch (mf2) 46 | { 47 | assert(false); 48 | } 49 | catch (mf1) 50 | { 51 | } 52 | } 53 | 54 | void test2() 55 | { 56 | try 57 | { 58 | throw &A::bar; 59 | assert(false); 60 | } 61 | catch (mf1) 62 | { 63 | assert(false); 64 | } 65 | catch (mf2) 66 | { 67 | } 68 | } 69 | 70 | 71 | 72 | void test_derived() 73 | { 74 | try 75 | { 76 | throw (mf1)0; 77 | assert(false); 78 | } 79 | catch (dmf2) 80 | { 81 | assert(false); 82 | } 83 | catch (dmf1) 84 | { 85 | assert(false); 86 | } 87 | catch (mf1) 88 | { 89 | } 90 | 91 | try 92 | { 93 | throw (mf2)0; 94 | assert(false); 95 | } 96 | catch (dmf1) 97 | { 98 | assert(false); 99 | } 100 | catch (dmf2) 101 | { 102 | assert(false); 103 | } 104 | catch (mf2) 105 | { 106 | } 107 | 108 | assert(!can_convert((dmf1)0)); 109 | assert(!can_convert((dmf1)0)); 110 | try 111 | { 112 | throw (dmf1)0; 113 | assert(false); 114 | } 115 | catch (mf2) 116 | { 117 | assert(false); 118 | } 119 | catch (mf1) 120 | { 121 | assert(false); 122 | } 123 | catch (...) 124 | { 125 | } 126 | 127 | assert(!can_convert((dmf2)0)); 128 | assert(!can_convert((dmf2)0)); 129 | try 130 | { 131 | throw (dmf2)0; 132 | assert(false); 133 | } 134 | catch (mf2) 135 | { 136 | assert(false); 137 | } 138 | catch (mf1) 139 | { 140 | assert(false); 141 | } 142 | catch (...) 143 | { 144 | } 145 | } 146 | 147 | void test_void() 148 | { 149 | assert(!can_convert(&A::foo)); 150 | try 151 | { 152 | throw &A::foo; 153 | assert(false); 154 | } 155 | catch (void*) 156 | { 157 | assert(false); 158 | } 159 | catch(...) 160 | { 161 | } 162 | } 163 | 164 | int main() 165 | { 166 | test1(); 167 | test2(); 168 | test_derived(); 169 | test_void(); 170 | } 171 | -------------------------------------------------------------------------------- /test/catch_member_function_pointer_02.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------- catch_member_function_pointer_02.cpp -----------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // Can a noexcept member function pointer be caught by a non-noexcept catch 10 | // clause? 11 | // UNSUPPORTED: libcxxabi-no-exceptions, libcxxabi-no-noexcept-function-type 12 | 13 | // GCC 7 and 8 support noexcept function types but this test still fails. 14 | // This is likely a bug in their implementation. Investigation needed. 15 | // XFAIL: gcc-7, gcc-8, gcc-9 16 | 17 | #include 18 | 19 | struct X { 20 | template void f() noexcept(Noexcept) {} 21 | }; 22 | template using FnType = void (X::*)() noexcept(Noexcept); 23 | 24 | template 25 | void check() 26 | { 27 | try 28 | { 29 | auto p = &X::f; 30 | throw p; 31 | assert(false); 32 | } 33 | catch (FnType p) 34 | { 35 | assert(ThrowNoexcept || !CatchNoexcept); 36 | assert(p == &X::f); 37 | } 38 | catch (...) 39 | { 40 | assert(!ThrowNoexcept && CatchNoexcept); 41 | } 42 | } 43 | 44 | void check_deep() { 45 | FnType p = &X::f; 46 | try 47 | { 48 | throw &p; 49 | } 50 | catch (FnType *q) 51 | { 52 | assert(false); 53 | } 54 | catch (FnType *q) 55 | { 56 | } 57 | catch (...) 58 | { 59 | assert(false); 60 | } 61 | } 62 | 63 | int main() 64 | { 65 | check(); 66 | check(); 67 | check(); 68 | check(); 69 | check_deep(); 70 | } 71 | -------------------------------------------------------------------------------- /test/catch_member_pointer_nullptr.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------- catch_member_pointer_nullptr.cpp -------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | 13 | #if __has_feature(cxx_nullptr) 14 | 15 | struct A 16 | { 17 | const int i; 18 | int j; 19 | }; 20 | 21 | typedef const int A::*md1; 22 | typedef int A::*md2; 23 | 24 | void test1() 25 | { 26 | try 27 | { 28 | throw nullptr; 29 | assert(false); 30 | } 31 | catch (md2 p) 32 | { 33 | assert(!p); 34 | } 35 | catch (md1) 36 | { 37 | assert(false); 38 | } 39 | } 40 | 41 | void test2() 42 | { 43 | try 44 | { 45 | throw nullptr; 46 | assert(false); 47 | } 48 | catch (md1 p) 49 | { 50 | assert(!p); 51 | } 52 | catch (md2) 53 | { 54 | assert(false); 55 | } 56 | } 57 | 58 | #else 59 | 60 | void test1() 61 | { 62 | } 63 | 64 | void test2() 65 | { 66 | } 67 | 68 | #endif 69 | 70 | int main() 71 | { 72 | test1(); 73 | test2(); 74 | } 75 | -------------------------------------------------------------------------------- /test/catch_multi_level_pointer.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------- catch_pointer_nullptr.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | // Roll our own assertion macro to get better error messages out of the tests. 16 | // In particular on systems that don't use __PRETTY_FUNCTION__ in assertions. 17 | #define my_assert(pred, msg) do_assert(pred, msg, __LINE__, __PRETTY_FUNCTION__) 18 | 19 | void do_assert(bool assert_passed, const char* msg, int line, const char* func) { 20 | if (assert_passed) return; 21 | std::cerr << __FILE__ << ":" << line << " " << func 22 | << ": Assertion Failed `" << msg << "'\n\n"; 23 | std::abort(); 24 | } 25 | 26 | struct A {}; 27 | struct Base {}; 28 | struct Derived : public Base {}; 29 | 30 | template 31 | bool test_conversion(To) { return true; } 32 | 33 | template 34 | bool test_conversion(...) { return false; } 35 | 36 | template 37 | struct CreatePointer { 38 | Pointer operator()() const { 39 | return (Pointer)0; 40 | } 41 | }; 42 | 43 | template 44 | struct CreatePointer { 45 | Tp* operator()() const { 46 | return (Tp*)42; 47 | } 48 | }; 49 | 50 | template 51 | void catch_pointer_test() { 52 | Throw throw_ptr = CreatePointer()(); 53 | // Use the compiler to determine if the exception of type Throw can be 54 | // implicitly converted to type Catch. 55 | const bool can_convert = test_conversion(throw_ptr); 56 | try { 57 | throw throw_ptr; 58 | assert(false); 59 | } catch (Catch catch_ptr) { 60 | Catch catch2 = CreatePointer()(); 61 | my_assert(can_convert, "non-convertible type incorrectly caught"); 62 | my_assert(catch_ptr == catch2, 63 | "Thrown pointer does not match caught ptr"); 64 | } catch (...) { 65 | my_assert(!can_convert, "convertible type incorrectly not caught"); 66 | } 67 | } 68 | 69 | // Generate CV qualified pointer typedefs. 70 | template 71 | struct TestTypes { 72 | typedef Tp* Type; 73 | typedef Tp const* CType; 74 | typedef Tp volatile* VType; 75 | typedef Tp const volatile* CVType; 76 | }; 77 | 78 | // Special case for cv-qualifying a pointer-to-member without adding an extra 79 | // pointer to it. 80 | template 81 | struct TestTypes { 82 | typedef Member (Class::*Type); 83 | typedef const Member (Class::*CType); 84 | typedef volatile Member (Class::*VType); 85 | typedef const volatile Member (Class::*CVType); 86 | }; 87 | 88 | template 89 | struct generate_tests_imp { 90 | typedef TestTypes ThrowTypes; 91 | typedef TestTypes CatchTypes; 92 | void operator()() { 93 | typedef typename ThrowTypes::Type Type; 94 | typedef typename ThrowTypes::CType CType; 95 | typedef typename ThrowTypes::VType VType; 96 | typedef typename ThrowTypes::CVType CVType; 97 | 98 | run_catch_tests(); 99 | run_catch_tests(); 100 | run_catch_tests(); 101 | run_catch_tests(); 102 | } 103 | 104 | template 105 | void run_catch_tests() { 106 | typedef typename CatchTypes::Type Type; 107 | typedef typename CatchTypes::CType CType; 108 | typedef typename CatchTypes::VType VType; 109 | typedef typename CatchTypes::CVType CVType; 110 | 111 | catch_pointer_test(); 112 | catch_pointer_test(); 113 | catch_pointer_test(); 114 | catch_pointer_test(); 115 | 116 | generate_tests_imp()(); 117 | generate_tests_imp()(); 118 | generate_tests_imp()(); 119 | generate_tests_imp()(); 120 | } 121 | }; 122 | 123 | template 124 | struct generate_tests_imp { 125 | void operator()() { 126 | catch_pointer_test(); 127 | } 128 | }; 129 | 130 | template 131 | struct generate_tests : generate_tests_imp {}; 132 | 133 | int main() 134 | { 135 | generate_tests()(); 136 | generate_tests()(); 137 | generate_tests()(); 138 | generate_tests()(); 139 | generate_tests()(); 140 | 141 | generate_tests()(); 142 | generate_tests()(); 143 | generate_tests()(); 144 | } 145 | -------------------------------------------------------------------------------- /test/catch_pointer_nullptr.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------- catch_pointer_nullptr.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | 14 | struct A {}; 15 | 16 | void test1() 17 | { 18 | try 19 | { 20 | throw nullptr; 21 | assert(false); 22 | } 23 | catch (int* p) 24 | { 25 | assert(!p); 26 | } 27 | catch (long*) 28 | { 29 | assert(false); 30 | } 31 | } 32 | 33 | void test2() 34 | { 35 | try 36 | { 37 | throw nullptr; 38 | assert(false); 39 | } 40 | catch (A* p) 41 | { 42 | assert(!p); 43 | } 44 | catch (int*) 45 | { 46 | assert(false); 47 | } 48 | } 49 | 50 | template 51 | void catch_nullptr_test() { 52 | try { 53 | throw nullptr; 54 | assert(false); 55 | } catch (Catch c) { 56 | assert(!c); 57 | } catch (...) { 58 | assert(false); 59 | } 60 | } 61 | 62 | 63 | int main() 64 | { 65 | // catch naked nullptrs 66 | test1(); 67 | test2(); 68 | 69 | catch_nullptr_test(); 70 | catch_nullptr_test(); 71 | catch_nullptr_test(); 72 | catch_nullptr_test(); 73 | catch_nullptr_test(); 74 | } 75 | -------------------------------------------------------------------------------- /test/catch_ptr.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------------- catch_class_04.cpp ----------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | /* 10 | This test checks that adjustedPtr is correct as there exist offsets in this 11 | object for the various subobjects, all of which have a unique id_ to 12 | check against. It also checks that virtual bases work properly 13 | */ 14 | 15 | // UNSUPPORTED: libcxxabi-no-exceptions 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | // Clang emits warnings about exceptions of type 'Child' being caught by 22 | // an earlier handler of type 'Base'. Congrats clang, you've just 23 | // diagnosed the behavior under test. 24 | #if defined(__clang__) 25 | #pragma clang diagnostic ignored "-Wexceptions" 26 | #endif 27 | 28 | struct B 29 | { 30 | static int count; 31 | int id_; 32 | explicit B(int id) : id_(id) {count++;} 33 | B(const B& a) : id_(a.id_) {count++;} 34 | ~B() {count--;} 35 | }; 36 | 37 | int B::count = 0; 38 | 39 | struct C1 40 | : virtual B 41 | { 42 | static int count; 43 | int id_; 44 | explicit C1(int id) : B(id-2), id_(id) {count++;} 45 | C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;} 46 | ~C1() {count--;} 47 | }; 48 | 49 | int C1::count = 0; 50 | 51 | struct C2 52 | : virtual private B 53 | { 54 | static int count; 55 | int id_; 56 | explicit C2(int id) : B(id-2), id_(id) {count++;} 57 | C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;} 58 | ~C2() {count--;} 59 | }; 60 | 61 | int C2::count = 0; 62 | 63 | struct A 64 | : C1, C2 65 | { 66 | static int count; 67 | int id_; 68 | explicit A(int id) : B(id+3), C1(id-1), C2(id-2), id_(id) {count++;} 69 | A(const A& a) : B(a.id_+3), C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;} 70 | ~A() {count--;} 71 | }; 72 | 73 | int A::count = 0; 74 | 75 | A a(5); 76 | 77 | void f1() 78 | { 79 | throw &a; 80 | assert(false); 81 | } 82 | 83 | void f2() 84 | { 85 | try 86 | { 87 | f1(); 88 | assert(false); 89 | } 90 | catch (const A* a) // can catch A 91 | { 92 | assert(a->id_ == 5); 93 | assert(static_cast(a)->id_ == 4); 94 | assert(static_cast(a)->id_ == 3); 95 | assert(static_cast(a)->id_ == 8); 96 | throw; 97 | } 98 | catch (const C1*) 99 | { 100 | assert(false); 101 | } 102 | catch (const C2*) 103 | { 104 | assert(false); 105 | } 106 | catch (const B*) 107 | { 108 | assert(false); 109 | } 110 | } 111 | 112 | void f3() 113 | { 114 | try 115 | { 116 | f2(); 117 | assert(false); 118 | } 119 | catch (const B* a) // can catch B 120 | { 121 | assert(static_cast(a)->id_ == 8); 122 | throw; 123 | } 124 | catch (const C1* c1) 125 | { 126 | assert(false); 127 | } 128 | catch (const C2*) 129 | { 130 | assert(false); 131 | } 132 | } 133 | 134 | void f4() 135 | { 136 | try 137 | { 138 | f3(); 139 | assert(false); 140 | } 141 | catch (const C2* c2) // can catch C2 142 | { 143 | assert(c2->id_ == 3); 144 | throw; 145 | } 146 | catch (const B* a) 147 | { 148 | assert(false); 149 | } 150 | catch (const C1*) 151 | { 152 | assert(false); 153 | } 154 | } 155 | 156 | void f5() 157 | { 158 | try 159 | { 160 | f4(); 161 | assert(false); 162 | } 163 | catch (const C1* c1) // can catch C1 164 | { 165 | assert(c1->id_ == 4); 166 | assert(static_cast(c1)->id_ == 8); 167 | throw; 168 | } 169 | catch (const B* a) 170 | { 171 | assert(false); 172 | } 173 | catch (const C2*) 174 | { 175 | assert(false); 176 | } 177 | } 178 | 179 | int main() 180 | { 181 | try 182 | { 183 | f5(); 184 | assert(false); 185 | } 186 | catch (...) 187 | { 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /test/catch_ptr_02.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- catch_ptr_02.cpp ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | 13 | // Clang emits warnings about exceptions of type 'Child' being caught by 14 | // an earlier handler of type 'Base'. Congrats clang, you've just 15 | // diagnosed the behavior under test. 16 | #if defined(__clang__) 17 | #pragma clang diagnostic ignored "-Wexceptions" 18 | #endif 19 | 20 | #if __cplusplus < 201103L 21 | #define DISABLE_NULLPTR_TESTS 22 | #endif 23 | 24 | struct A {}; 25 | A a; 26 | const A ca = A(); 27 | 28 | void test1 () 29 | { 30 | try 31 | { 32 | throw &a; 33 | assert(false); 34 | } 35 | catch ( const A* ) 36 | { 37 | } 38 | catch ( A *) 39 | { 40 | assert (false); 41 | } 42 | } 43 | 44 | void test2 () 45 | { 46 | try 47 | { 48 | throw &a; 49 | assert(false); 50 | } 51 | catch ( A* ) 52 | { 53 | } 54 | catch ( const A *) 55 | { 56 | assert (false); 57 | } 58 | } 59 | 60 | void test3 () 61 | { 62 | try 63 | { 64 | throw &ca; 65 | assert(false); 66 | } 67 | catch ( const A* ) 68 | { 69 | } 70 | catch ( A *) 71 | { 72 | assert (false); 73 | } 74 | } 75 | 76 | void test4 () 77 | { 78 | try 79 | { 80 | throw &ca; 81 | assert(false); 82 | } 83 | catch ( A *) 84 | { 85 | assert (false); 86 | } 87 | catch ( const A* ) 88 | { 89 | } 90 | } 91 | 92 | struct base1 {int x;}; 93 | struct base2 {int x;}; 94 | struct derived : base1, base2 {}; 95 | 96 | void test5 () 97 | { 98 | try 99 | { 100 | throw (derived*)0; 101 | assert(false); 102 | } 103 | catch (base2 *p) { 104 | assert (p == 0); 105 | } 106 | catch (...) 107 | { 108 | assert (false); 109 | } 110 | } 111 | 112 | void test6 () 113 | { 114 | #if !defined(DISABLE_NULLPTR_TESTS) 115 | try 116 | { 117 | throw nullptr; 118 | assert(false); 119 | } 120 | catch (base2 *p) { 121 | assert (p == nullptr); 122 | } 123 | catch (...) 124 | { 125 | assert (false); 126 | } 127 | #endif 128 | } 129 | 130 | void test7 () 131 | { 132 | try 133 | { 134 | throw (derived*)12; 135 | assert(false); 136 | } 137 | catch (base2 *p) { 138 | assert ((unsigned long)p == 12+sizeof(base1)); 139 | } 140 | catch (...) 141 | { 142 | assert (false); 143 | } 144 | } 145 | 146 | 147 | struct vBase {}; 148 | struct vDerived : virtual public vBase {}; 149 | 150 | void test8 () 151 | { 152 | vDerived derived; 153 | try 154 | { 155 | throw &derived; 156 | assert(false); 157 | } 158 | catch (vBase *p) { 159 | assert(p != 0); 160 | } 161 | catch (...) 162 | { 163 | assert (false); 164 | } 165 | } 166 | 167 | void test9 () 168 | { 169 | #if !defined(DISABLE_NULLPTR_TESTS) 170 | try 171 | { 172 | throw nullptr; 173 | assert(false); 174 | } 175 | catch (vBase *p) { 176 | assert(p == 0); 177 | } 178 | catch (...) 179 | { 180 | assert (false); 181 | } 182 | #endif 183 | } 184 | 185 | void test10 () 186 | { 187 | try 188 | { 189 | throw (vDerived*)0; 190 | assert(false); 191 | } 192 | catch (vBase *p) { 193 | assert(p == 0); 194 | } 195 | catch (...) 196 | { 197 | assert (false); 198 | } 199 | } 200 | 201 | int main() 202 | { 203 | test1(); 204 | test2(); 205 | test3(); 206 | test4(); 207 | test5(); 208 | test6(); 209 | test7(); 210 | test8(); 211 | test9(); 212 | test10(); 213 | } 214 | -------------------------------------------------------------------------------- /test/catch_reference_nullptr.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------- catch_pointer_nullptr.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03, libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | 14 | struct A {}; 15 | 16 | template 17 | static void catch_nullptr_test() { 18 | try { 19 | throw nullptr; 20 | } catch (T &p) { 21 | assert(CanCatchNullptr && !static_cast(p)); 22 | } catch (...) { 23 | assert(!CanCatchNullptr); 24 | } 25 | } 26 | 27 | int main() 28 | { 29 | using nullptr_t = decltype(nullptr); 30 | 31 | // A reference to nullptr_t can catch nullptr. 32 | catch_nullptr_test(); 33 | catch_nullptr_test(); 34 | catch_nullptr_test(); 35 | catch_nullptr_test(); 36 | 37 | // No other reference type can. 38 | #if 0 39 | // FIXME: These tests fail, because the ABI provides no way for us to 40 | // distinguish this from catching by value. 41 | catch_nullptr_test(); 42 | catch_nullptr_test(); 43 | catch_nullptr_test(); 44 | catch_nullptr_test(); 45 | catch_nullptr_test(); 46 | catch_nullptr_test(); 47 | #endif 48 | } 49 | -------------------------------------------------------------------------------- /test/cxa_bad_cast.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- cxa_bad_cast.pass.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | class Base { 18 | virtual void foo() {}; 19 | }; 20 | 21 | class Derived : public Base {}; 22 | 23 | Derived &test_bad_cast(Base& b) { 24 | return dynamic_cast(b); 25 | } 26 | 27 | Base gB; 28 | 29 | void my_terminate() { exit(0); } 30 | 31 | int main () 32 | { 33 | // swap-out the terminate handler 34 | void (*default_handler)() = std::get_terminate(); 35 | std::set_terminate(my_terminate); 36 | 37 | #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS 38 | try { 39 | #endif 40 | Derived &d = test_bad_cast(gB); 41 | assert(false); 42 | ((void)d); 43 | #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS 44 | } catch (std::bad_cast) { 45 | // success 46 | return 0; 47 | } catch (...) { 48 | assert(false); 49 | } 50 | #endif 51 | 52 | // failure, restore the default terminate handler and fire 53 | std::set_terminate(default_handler); 54 | std::terminate(); 55 | } 56 | -------------------------------------------------------------------------------- /test/cxa_bad_typeid.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- cxa_bad_typeid.pass.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===------------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | class Base { 20 | virtual void foo() {}; 21 | }; 22 | 23 | class Derived : public Base {}; 24 | 25 | std::string test_bad_typeid(Derived *p) { 26 | return typeid(*p).name(); 27 | } 28 | 29 | void my_terminate() { std::cout << "A" << std::endl; exit(0); } 30 | 31 | int main () 32 | { 33 | // swap-out the terminate handler 34 | void (*default_handler)() = std::get_terminate(); 35 | std::set_terminate(my_terminate); 36 | 37 | #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS 38 | try { 39 | #endif 40 | test_bad_typeid(nullptr); 41 | assert(false); 42 | #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS 43 | } catch (std::bad_typeid) { 44 | // success 45 | return 0; 46 | } catch (...) { 47 | assert(false); 48 | } 49 | #endif 50 | 51 | // failure, restore the default terminate handler and fire 52 | std::set_terminate(default_handler); 53 | std::terminate(); 54 | } 55 | -------------------------------------------------------------------------------- /test/cxa_thread_atexit_test.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------- cxa_thread_atexit_test.cpp ---------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-threads 10 | // REQUIRES: linux 11 | 12 | #include 13 | #include 14 | 15 | static bool AtexitImplCalled = false; 16 | 17 | extern "C" int __cxa_thread_atexit_impl(void (*dtor)(void *), void *obj, 18 | void *dso_symbol) { 19 | assert(dtor == reinterpret_cast(1)); 20 | assert(obj == reinterpret_cast(2)); 21 | assert(dso_symbol == reinterpret_cast(3)); 22 | AtexitImplCalled = true; 23 | return 4; 24 | } 25 | 26 | int main() { 27 | int RV = __cxxabiv1::__cxa_thread_atexit( 28 | reinterpret_cast(1), reinterpret_cast(2), 29 | reinterpret_cast(3)); 30 | assert(RV == 4); 31 | assert(AtexitImplCalled); 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /test/dynamic_cast.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- dynamic_cast.pass.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include 10 | 11 | // This test explicitly tests dynamic cast with types that have inaccessible 12 | // bases. 13 | #if defined(__clang__) 14 | #pragma clang diagnostic ignored "-Winaccessible-base" 15 | #endif 16 | 17 | typedef char Pad1[43981]; 18 | typedef char Pad2[34981]; 19 | typedef char Pad3[93481]; 20 | typedef char Pad4[13489]; 21 | typedef char Pad5[81349]; 22 | typedef char Pad6[34819]; 23 | typedef char Pad7[3489]; 24 | 25 | namespace t1 26 | { 27 | 28 | // PR33425 29 | struct C3 { virtual ~C3() {} Pad1 _; }; 30 | struct C5 : protected virtual C3 { Pad2 _; }; 31 | struct C6 : virtual C5 { Pad3 _; }; 32 | struct C7 : virtual C3 { Pad4 _; }; 33 | struct C9 : C6, C7 { Pad5 _; }; 34 | 35 | C9 c9; 36 | C3 *c3 = &c9; 37 | 38 | void test() 39 | { 40 | assert(dynamic_cast(c3) == static_cast(&c9)); 41 | assert(dynamic_cast(c3) == static_cast(&c9)); 42 | assert(dynamic_cast(c3) == static_cast(&c9)); 43 | assert(dynamic_cast(c3) == static_cast(&c9)); 44 | assert(dynamic_cast(c3) == static_cast(&c9)); 45 | } 46 | 47 | } // t1 48 | 49 | namespace t2 50 | { 51 | 52 | // PR33425 53 | struct Src { virtual ~Src() {} Pad1 _; }; 54 | struct Mask : protected virtual Src { Pad2 _; }; 55 | struct Dest : Mask { Pad3 _; }; 56 | struct Root : Dest, virtual Src { Pad4 _; }; 57 | 58 | Root root; 59 | Src *src = &root; 60 | 61 | void test() 62 | { 63 | assert(dynamic_cast(src) == static_cast(&root)); 64 | assert(dynamic_cast(src) == static_cast(&root)); 65 | assert(dynamic_cast(src) == static_cast(&root)); 66 | assert(dynamic_cast(src) == static_cast(&root)); 67 | } 68 | 69 | } // t2 70 | 71 | namespace t3 72 | { 73 | 74 | // PR33487 75 | struct Class1 { virtual ~Class1() {} Pad1 _; }; 76 | struct Shared : virtual Class1 { Pad2 _; }; 77 | struct Class6 : virtual Shared { Pad3 _; }; 78 | struct Left : Class6 { Pad4 _; }; 79 | struct Right : Class6 { Pad5 _; }; 80 | struct Main : Left, Right { Pad6 _; }; 81 | 82 | Main m; 83 | Class1 *c1 = &m; 84 | 85 | void test() 86 | { 87 | assert(dynamic_cast(c1) == static_cast(&m)); 88 | assert(dynamic_cast(c1) == static_cast(&m)); 89 | assert(dynamic_cast(c1) == 0); 90 | assert(dynamic_cast(c1) == static_cast(&m)); 91 | assert(dynamic_cast(c1) == static_cast(&m)); 92 | assert(dynamic_cast(c1) == static_cast(&m)); 93 | } 94 | 95 | } // t3 96 | 97 | namespace t4 98 | { 99 | 100 | // PR33439 101 | struct C2 { virtual ~C2() {} Pad1 _; }; 102 | struct C3 { virtual ~C3() {} Pad2 _; }; 103 | struct C4 : C3 { Pad3 _; }; 104 | struct C8 : C2, virtual C4 { Pad4 _; }; 105 | struct C9 : C4, C8 { Pad5 _; }; 106 | 107 | C9 c9; 108 | C2 *c2 = &c9; 109 | 110 | void test() 111 | { 112 | assert(dynamic_cast(c2) == static_cast(&c9)); 113 | assert(dynamic_cast(c2) == 0); 114 | assert(dynamic_cast(c2) == 0); 115 | assert(dynamic_cast(c2) == static_cast(&c9)); 116 | assert(dynamic_cast(c2) == static_cast(&c9)); 117 | } 118 | 119 | } // t4 120 | 121 | namespace t5 122 | { 123 | 124 | // PR33439 125 | struct Dummy { virtual ~Dummy() {} Pad1 _; }; 126 | struct Src { virtual ~Src() {} Pad2 _; }; 127 | struct Dest : Dummy { Pad3 _; }; 128 | struct A1 : Dest { Pad4 _; }; 129 | struct A2 : Dest { Pad5 _; }; 130 | struct Root : Src, A1, A2 { Pad6 _; }; 131 | 132 | Root root; 133 | Src *src = &root; 134 | 135 | void test() 136 | { 137 | assert(dynamic_cast(src) == 0); 138 | assert(dynamic_cast(src) == static_cast(&root)); 139 | assert(dynamic_cast(src) == 0); 140 | assert(dynamic_cast(src) == static_cast(&root)); 141 | assert(dynamic_cast(src) == static_cast(&root)); 142 | } 143 | 144 | } // t5 145 | 146 | int main() 147 | { 148 | t1::test(); 149 | t2::test(); 150 | t3::test(); 151 | t4::test(); 152 | t5::test(); 153 | } 154 | -------------------------------------------------------------------------------- /test/dynamic_cast_stress.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- dynamic_cast_stress.cpp --------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03 10 | 11 | #include 12 | #include 13 | #include "support/timer.hpp" 14 | 15 | template 16 | struct C 17 | : public virtual C, 18 | public virtual C 19 | { 20 | virtual ~C() {} 21 | }; 22 | 23 | template 24 | struct C 25 | { 26 | virtual ~C() {} 27 | }; 28 | 29 | template 30 | struct B 31 | : public virtual C, 32 | public virtual C 33 | { 34 | }; 35 | 36 | template 37 | struct makeB; 38 | 39 | template 40 | struct makeB, Depth> 41 | : public B... 42 | { 43 | }; 44 | 45 | template 46 | struct A 47 | : public makeB::type, Depth> 48 | { 49 | }; 50 | 51 | void test() 52 | { 53 | const std::size_t Width = 10; 54 | const std::size_t Depth = 5; 55 | A a; 56 | typedef B Destination; 57 | // typedef A Destination; 58 | Destination *b = nullptr; 59 | { 60 | timer t; 61 | b = dynamic_cast((C*)&a); 62 | } 63 | assert(b != 0); 64 | } 65 | 66 | int main() 67 | { 68 | test(); 69 | } 70 | 71 | /* 72 | Timing results I'm seeing (median of 3 microseconds): 73 | 74 | libc++abi gcc's dynamic_cast 75 | B -O3 48.334 93.190 libc++abi 93% faster 76 | B -Os 58.535 94.103 libc++abi 61% faster 77 | A -O3 11.515 33.134 libc++abi 188% faster 78 | A -Os 12.631 31.553 libc++abi 150% faster 79 | 80 | */ 81 | -------------------------------------------------------------------------------- /test/exception_object_alignment.pass.cpp: -------------------------------------------------------------------------------- 1 | //===---------------- exception_object_alignment.pass.cpp -----------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | // Check that the pointer __cxa_allocate_exception returns is aligned to the 12 | // default alignment for the target architecture. 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include <__cxxabi_config.h> 19 | 20 | struct S { 21 | int a[4]; 22 | } __attribute__((aligned)); 23 | 24 | int main() { 25 | #if !defined(_LIBCXXABI_ARM_EHABI) 26 | void *p = __cxxabiv1::__cxa_allocate_exception(16); 27 | auto i = reinterpret_cast(p); 28 | auto a = std::alignment_of::value; 29 | assert(i % a == 0); 30 | __cxxabiv1::__cxa_free_exception(p); 31 | #endif 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /test/inherited_exception.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------- inherited_exception.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | // 9 | // This test case checks specifically the cases under C++ ABI 15.3.1, and 15.3.2 10 | // 11 | // C++ ABI 15.3: 12 | // A handler is a match for an exception object of type E if 13 | // / * The handler is of type cv T or cv T& and E and T are the same type \ 14 | // | (ignoring the top-level cv-qualifiers), or | 15 | // | * the handler is of type cv T or cv T& and T is an unambiguous base | 16 | // \ class of E, or / 17 | // * the handler is of type cv1 T* cv2 and E is a pointer type that can 18 | // be converted to the type of the handler by either or both of 19 | // o a standard pointer conversion (4.10 [conv.ptr]) not involving 20 | // conversions to private or protected or ambiguous classes 21 | // o a qualification conversion 22 | // * the handler is a pointer or pointer to member type and E is 23 | // std::nullptr_t 24 | // 25 | //===----------------------------------------------------------------------===// 26 | 27 | // UNSUPPORTED: libcxxabi-no-exceptions 28 | 29 | // Clang emits warnings about exceptions of type 'Child' being caught by 30 | // an earlier handler of type 'Base'. Congrats clang, you've just 31 | // diagnosed the behavior under test. 32 | #if defined(__clang__) 33 | #pragma clang diagnostic ignored "-Wexceptions" 34 | #endif 35 | 36 | #include 37 | 38 | struct Base { 39 | int b1; 40 | }; 41 | 42 | struct Base2 { 43 | int b2; 44 | }; 45 | 46 | struct Child : public Base, public Base2 { 47 | int c; 48 | }; 49 | 50 | void f1() { 51 | Child child; 52 | child.b1 = 10; 53 | child.b2 = 11; 54 | child.c = 12; 55 | throw child; 56 | } 57 | 58 | void f2() { 59 | Child child; 60 | child.b1 = 10; 61 | child.b2 = 11; 62 | child.c = 12; 63 | throw static_cast(child); 64 | } 65 | 66 | void f3() { 67 | static Child child; 68 | child.b1 = 10; 69 | child.b2 = 11; 70 | child.c = 12; 71 | throw static_cast(&child); 72 | } 73 | 74 | int main() 75 | { 76 | try 77 | { 78 | f1(); 79 | assert(false); 80 | } 81 | catch (const Child& c) 82 | { 83 | assert(true); 84 | } 85 | catch (const Base& b) 86 | { 87 | assert(false); 88 | } 89 | catch (...) 90 | { 91 | assert(false); 92 | } 93 | 94 | try 95 | { 96 | f1(); 97 | assert(false); 98 | } 99 | catch (const Base& c) 100 | { 101 | assert(true); 102 | } 103 | catch (const Child& b) 104 | { 105 | assert(false); 106 | } 107 | catch (...) 108 | { 109 | assert(false); 110 | } 111 | 112 | try 113 | { 114 | f1(); 115 | assert(false); 116 | } 117 | catch (const Base2& c) 118 | { 119 | assert(true); 120 | } 121 | catch (const Child& b) 122 | { 123 | assert(false); 124 | } 125 | catch (...) 126 | { 127 | assert(false); 128 | } 129 | 130 | try 131 | { 132 | f2(); 133 | assert(false); 134 | } 135 | catch (const Child& c) 136 | { 137 | assert(false); 138 | } 139 | catch (const Base& b) 140 | { 141 | assert(false); 142 | } 143 | catch (const Base2& b) 144 | { 145 | assert(true); 146 | } 147 | catch (...) 148 | { 149 | assert(false); 150 | } 151 | 152 | try 153 | { 154 | f3(); 155 | assert(false); 156 | } 157 | catch (const Base* c) 158 | { 159 | assert(false); 160 | } 161 | catch (const Child* b) 162 | { 163 | assert(false); 164 | } 165 | catch (const Base2* c) 166 | { 167 | assert(true); 168 | } 169 | catch (...) 170 | { 171 | assert(false); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /test/libcxxabi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leaningtech/cheerp-libcxxabi/81ad0b7860e51de2e36aec4b8178277c41aeffba/test/libcxxabi/__init__.py -------------------------------------------------------------------------------- /test/libcxxabi/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leaningtech/cheerp-libcxxabi/81ad0b7860e51de2e36aec4b8178277c41aeffba/test/libcxxabi/test/__init__.py -------------------------------------------------------------------------------- /test/libcxxabi/test/config.py: -------------------------------------------------------------------------------- 1 | #===----------------------------------------------------------------------===## 2 | # 3 | # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | # See https://llvm.org/LICENSE.txt for license information. 5 | # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | # 7 | #===----------------------------------------------------------------------===## 8 | import os 9 | import sys 10 | 11 | from libcxx.test.config import Configuration as LibcxxConfiguration 12 | from libcxx.test.config import intMacroValue 13 | 14 | 15 | class Configuration(LibcxxConfiguration): 16 | # pylint: disable=redefined-outer-name 17 | def __init__(self, lit_config, config): 18 | super(Configuration, self).__init__(lit_config, config) 19 | self.libcxxabi_src_root = None 20 | self.libcxxabi_obj_root = None 21 | self.abi_library_path = None 22 | self.libcxx_src_root = None 23 | 24 | def configure_src_root(self): 25 | self.libcxxabi_src_root = self.get_lit_conf( 26 | 'libcxxabi_src_root', 27 | os.path.dirname(self.config.test_source_root)) 28 | self.libcxx_src_root = self.get_lit_conf( 29 | 'libcxx_src_root', 30 | os.path.join(self.libcxxabi_src_root, '/../libcxx')) 31 | 32 | def configure_obj_root(self): 33 | self.libcxxabi_obj_root = self.get_lit_conf('libcxxabi_obj_root') 34 | super(Configuration, self).configure_obj_root() 35 | 36 | def has_cpp_feature(self, feature, required_value): 37 | return intMacroValue(self.cxx.dumpMacros().get('__cpp_' + feature, '0')) >= required_value 38 | 39 | def configure_features(self): 40 | super(Configuration, self).configure_features() 41 | if not self.get_lit_bool('enable_exceptions', True): 42 | self.config.available_features.add('libcxxabi-no-exceptions') 43 | if not self.has_cpp_feature('noexcept_function_type', 201510): 44 | self.config.available_features.add('libcxxabi-no-noexcept-function-type') 45 | # test_exception_storage_nodynmem.pass.cpp fails under this specific configuration 46 | if self.get_lit_bool('cxx_ext_threads', False) and self.get_lit_bool('libcxxabi_shared', False): 47 | self.config.available_features.add('libcxxabi-shared-externally-threaded') 48 | if not self.get_lit_bool('llvm_unwinder', False): 49 | self.config.available_features.add('libcxxabi-has-system-unwinder') 50 | 51 | def configure_compile_flags(self): 52 | self.cxx.compile_flags += [ 53 | '-DLIBCXXABI_NO_TIMER', 54 | '-D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS', 55 | ] 56 | if self.get_lit_bool('enable_exceptions', True): 57 | self.cxx.compile_flags += ['-funwind-tables'] 58 | else: 59 | self.cxx.compile_flags += ['-fno-exceptions', '-DLIBCXXABI_HAS_NO_EXCEPTIONS'] 60 | if not self.get_lit_bool('enable_threads', True): 61 | self.cxx.compile_flags += ['-D_LIBCXXABI_HAS_NO_THREADS'] 62 | self.config.available_features.add('libcxxabi-no-threads') 63 | super(Configuration, self).configure_compile_flags() 64 | 65 | def configure_compile_flags_header_includes(self): 66 | self.configure_config_site_header() 67 | cxx_headers = self.get_lit_conf( 68 | 'cxx_headers', 69 | os.path.join(self.libcxx_src_root, '/include')) 70 | if cxx_headers == '': 71 | self.lit_config.note('using the systems c++ headers') 72 | else: 73 | self.cxx.compile_flags += ['-nostdinc++'] 74 | if not os.path.isdir(cxx_headers): 75 | self.lit_config.fatal("cxx_headers='%s' is not a directory." 76 | % cxx_headers) 77 | self.cxx.compile_flags += ['-I' + cxx_headers] 78 | 79 | libcxxabi_headers = self.get_lit_conf( 80 | 'libcxxabi_headers', 81 | os.path.join(self.libcxxabi_src_root, 'include')) 82 | if not os.path.isdir(libcxxabi_headers): 83 | self.lit_config.fatal("libcxxabi_headers='%s' is not a directory." 84 | % libcxxabi_headers) 85 | self.cxx.compile_flags += ['-I' + libcxxabi_headers] 86 | 87 | libunwind_headers = self.get_lit_conf('libunwind_headers', None) 88 | if self.get_lit_bool('llvm_unwinder', False) and libunwind_headers: 89 | if not os.path.isdir(libunwind_headers): 90 | self.lit_config.fatal("libunwind_headers='%s' is not a directory." 91 | % libunwind_headers) 92 | self.cxx.compile_flags += ['-I' + libunwind_headers] 93 | 94 | def configure_compile_flags_exceptions(self): 95 | pass 96 | 97 | def configure_compile_flags_rtti(self): 98 | pass 99 | -------------------------------------------------------------------------------- /test/lit.cfg: -------------------------------------------------------------------------------- 1 | # -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79: 2 | 3 | # Configuration file for the 'lit' test runner. 4 | 5 | 6 | import os 7 | import site 8 | 9 | site.addsitedir(os.path.dirname(__file__)) 10 | 11 | 12 | # Tell pylint that we know config and lit_config exist somewhere. 13 | if 'PYLINT_IMPORT' in os.environ: 14 | config = object() 15 | lit_config = object() 16 | 17 | # name: The name of this test suite. 18 | config.name = 'libc++abi' 19 | 20 | # suffixes: A list of file extensions to treat as test files. 21 | config.suffixes = ['.cpp', '.s'] 22 | 23 | # test_source_root: The root path where tests are located. 24 | config.test_source_root = os.path.dirname(__file__) 25 | 26 | # Infer the libcxx_test_source_root for configuration import. 27 | # If libcxx_source_root isn't specified in the config, assume that the libcxx 28 | # and libcxxabi source directories are sibling directories. 29 | libcxx_src_root = getattr(config, 'libcxx_src_root', None) 30 | if not libcxx_src_root: 31 | libcxx_src_root = os.path.join(config.test_source_root, '../../libcxx') 32 | libcxx_test_src_root = os.path.join(libcxx_src_root, 'utils') 33 | if os.path.isfile(os.path.join(libcxx_test_src_root, 'libcxx', '__init__.py')): 34 | site.addsitedir(libcxx_test_src_root) 35 | else: 36 | lit_config.fatal('Could not find libcxx test directory for test imports' 37 | ' in: %s' % libcxx_test_src_root) 38 | 39 | # Infer the test_exec_root from the libcxx_object root. 40 | obj_root = getattr(config, 'libcxxabi_obj_root', None) 41 | 42 | # Check that the test exec root is known. 43 | if obj_root is None: 44 | import libcxx.test.config 45 | libcxx.test.config.loadSiteConfig( 46 | lit_config, config, 'libcxxabi_site_config', 'LIBCXXABI_SITE_CONFIG') 47 | obj_root = getattr(config, 'libcxxabi_obj_root', None) 48 | if obj_root is None: 49 | import tempfile 50 | obj_root = tempfile.mkdtemp(prefix='libcxxabi-testsuite-') 51 | lit_config.warning('Creating temporary directory for object root: %s' % 52 | obj_root) 53 | 54 | config.test_exec_root = os.path.join(obj_root, 'test') 55 | 56 | cfg_variant = getattr(config, 'configuration_variant', 'libcxxabi') 57 | if cfg_variant: 58 | lit_config.note('Using configuration variant: %s' % cfg_variant) 59 | 60 | # Load the Configuration class from the module name .test.config. 61 | config_module_name = '.'.join([cfg_variant, 'test', 'config']) 62 | config_module = __import__(config_module_name, fromlist=['Configuration']) 63 | 64 | configuration = config_module.Configuration(lit_config, config) 65 | configuration.configure() 66 | configuration.print_config_info() 67 | config.test_format = configuration.get_test_format() 68 | -------------------------------------------------------------------------------- /test/lit.site.cfg.in: -------------------------------------------------------------------------------- 1 | @AUTO_GEN_COMMENT@ 2 | config.cxx_under_test = "@LIBCXXABI_COMPILER@" 3 | config.project_obj_root = "@CMAKE_BINARY_DIR@" 4 | config.libcxxabi_src_root = "@LIBCXXABI_SOURCE_DIR@" 5 | config.libcxxabi_obj_root = "@LIBCXXABI_BINARY_DIR@" 6 | config.abi_library_path = "@LIBCXXABI_LIBRARY_DIR@" 7 | config.libcxx_src_root = "@LIBCXXABI_LIBCXX_PATH@" 8 | config.cxx_headers = "@LIBCXXABI_LIBCXX_INCLUDES@" 9 | config.libunwind_headers = "@LIBCXXABI_LIBUNWIND_INCLUDES_INTERNAL@" 10 | config.cxx_library_root = "@LIBCXXABI_LIBCXX_LIBRARY_PATH@" 11 | config.llvm_unwinder = "@LIBCXXABI_USE_LLVM_UNWINDER@" 12 | config.enable_threads = "@LIBCXXABI_ENABLE_THREADS@" 13 | config.use_sanitizer = "@LLVM_USE_SANITIZER@" 14 | config.sanitizer_library = "@LIBCXXABI_SANITIZER_LIBRARY@" 15 | config.enable_32bit = "@LIBCXXABI_BUILD_32_BITS@" 16 | config.target_info = "@LIBCXXABI_TARGET_INFO@" 17 | config.executor = "@LIBCXXABI_EXECUTOR@" 18 | config.libcxxabi_shared = "@LIBCXXABI_ENABLE_SHARED@" 19 | config.enable_shared = "@LIBCXX_ENABLE_SHARED@" 20 | config.enable_exceptions = "@LIBCXXABI_ENABLE_EXCEPTIONS@" 21 | config.host_triple = "@LLVM_HOST_TRIPLE@" 22 | config.target_triple = "@TARGET_TRIPLE@" 23 | config.use_target = len("@LIBCXXABI_TARGET_TRIPLE@") > 0 24 | config.sysroot = "@LIBCXXABI_SYSROOT@" 25 | config.gcc_toolchain = "@LIBCXXABI_GCC_TOOLCHAIN@" 26 | config.cxx_ext_threads = "@LIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY@" 27 | 28 | # Let the main config do the real work. 29 | lit_config.load_config(config, "@LIBCXXABI_SOURCE_DIR@/test/lit.cfg") 30 | -------------------------------------------------------------------------------- /test/native/arm-linux-eabi/lit.local.cfg: -------------------------------------------------------------------------------- 1 | def is_arm_linux_eabi(triple): 2 | return ('arm' in triple) and ('linux' in triple) and ('eabi' in triple) 3 | 4 | is_native = config.root.host_triple == config.root.target_triple 5 | if not is_native or not is_arm_linux_eabi(config.root.host_triple): 6 | config.unsupported = True 7 | -------------------------------------------------------------------------------- /test/native/arm-linux-eabi/ttype-encoding-00.pass.sh.s: -------------------------------------------------------------------------------- 1 | @ RUN: %cxx %flags %link_flags %s -o %t.exe 2 | @ RUN: %t.exe 3 | @ UNSUPPORTED: libcxxabi-no-exceptions 4 | 5 | @ PURPOSE: Check that 0x00 is a valid value for ttype encoding. LLVM and 6 | @ GCC 4.6 are generating 0x00 as ttype encoding. libc++abi should provide 7 | @ legacy support. 8 | 9 | @ NOTE: 10 | @ 11 | @ This file is generated from the following C++ source code: 12 | @ 13 | @ ``` 14 | @ int main() { 15 | @ try { 16 | @ throw 5; 17 | @ } catch (int i) { 18 | @ if (i != 5) 19 | @ abort(); 20 | @ return 0; 21 | @ } 22 | @ } 23 | @ ``` 24 | 25 | .syntax unified 26 | 27 | .text 28 | .globl main 29 | .p2align 2 30 | .type main,%function 31 | main: @ @main 32 | .Lfunc_begin0: 33 | .fnstart 34 | @ BB#0: @ %entry 35 | .save {r11, lr} 36 | push {r11, lr} 37 | .setfp r11, sp 38 | mov r11, sp 39 | mov r0, #4 40 | bl __cxa_allocate_exception 41 | mov r1, #5 42 | str r1, [r0] 43 | .Ltmp0: 44 | ldr r1, .LCPI0_0 45 | mov r2, #0 46 | bl __cxa_throw 47 | .Ltmp1: 48 | 49 | @ BB#2: @ %lpad 50 | .Ltmp2: 51 | bl __cxa_begin_catch 52 | ldr r0, [r0] 53 | cmp r0, #5 54 | bne .LBB0_4 55 | @ BB#3: @ %if.end 56 | bl __cxa_end_catch 57 | mov r0, #0 58 | pop {r11, lr} 59 | bx lr 60 | .LBB0_4: @ %if.then 61 | bl abort 62 | .p2align 2 63 | @ BB#5: 64 | .LCPI0_0: 65 | .long _ZTIi 66 | .Lfunc_end0: 67 | 68 | .size main, .Lfunc_end0-main 69 | .globl __gxx_personality_v0 70 | .personality __gxx_personality_v0 71 | .handlerdata 72 | .p2align 2 73 | GCC_except_table0: 74 | .Lexception0: 75 | .byte 255 @ @LPStart Encoding = omit 76 | .byte 0 @ @TType Encoding = absptr 77 | .asciz "\257\200" @ @TType base offset 78 | .byte 3 @ Call site Encoding = udata4 79 | .byte 39 @ Call site table length 80 | .long .Lfunc_begin0-.Lfunc_begin0 @ >> Call Site 1 << 81 | .long .Ltmp0-.Lfunc_begin0 @ Call between .Lfunc_begin0 and .Ltmp0 82 | .long 0 @ has no landing pad 83 | .byte 0 @ On action: cleanup 84 | .long .Ltmp0-.Lfunc_begin0 @ >> Call Site 2 << 85 | .long .Ltmp1-.Ltmp0 @ Call between .Ltmp0 and .Ltmp1 86 | .long .Ltmp2-.Lfunc_begin0 @ jumps to .Ltmp2 87 | .byte 1 @ On action: 1 88 | .long .Ltmp1-.Lfunc_begin0 @ >> Call Site 3 << 89 | .long .Lfunc_end0-.Ltmp1 @ Call between .Ltmp1 and .Lfunc_end0 90 | .long 0 @ has no landing pad 91 | .byte 0 @ On action: cleanup 92 | .byte 1 @ >> Action Record 1 << 93 | @ Catch TypeInfo 1 94 | .byte 0 @ No further actions 95 | @ >> Catch TypeInfos << 96 | .long _ZTIi(target2) @ TypeInfo 1 97 | .p2align 2 98 | .fnend 99 | -------------------------------------------------------------------------------- /test/native/arm-linux-eabi/ttype-encoding-90.pass.sh.s: -------------------------------------------------------------------------------- 1 | @ RUN: %cxx %flags %link_flags %s -o %t.exe 2 | @ RUN: %t.exe 3 | @ UNSUPPORTED: libcxxabi-no-exceptions 4 | 5 | @ PURPOSE: Check that 0x90 is a valid value for ttype encoding. 6 | 7 | @ NOTE: 8 | @ 9 | @ This file is generated from the following C++ source code and then change the 10 | @ `TType Encoding` to 0x90. 11 | @ 12 | @ ``` 13 | @ int main() { 14 | @ try { 15 | @ throw 5; 16 | @ } catch (int i) { 17 | @ if (i != 5) 18 | @ abort(); 19 | @ return 0; 20 | @ } 21 | @ } 22 | @ ``` 23 | 24 | .syntax unified 25 | 26 | .text 27 | .globl main 28 | .p2align 2 29 | .type main,%function 30 | main: @ @main 31 | .Lfunc_begin0: 32 | .fnstart 33 | @ BB#0: @ %entry 34 | .save {r11, lr} 35 | push {r11, lr} 36 | .setfp r11, sp 37 | mov r11, sp 38 | mov r0, #4 39 | bl __cxa_allocate_exception 40 | mov r1, #5 41 | str r1, [r0] 42 | .Ltmp0: 43 | ldr r1, .LCPI0_0 44 | mov r2, #0 45 | bl __cxa_throw 46 | .Ltmp1: 47 | 48 | @ BB#2: @ %lpad 49 | .Ltmp2: 50 | bl __cxa_begin_catch 51 | ldr r0, [r0] 52 | cmp r0, #5 53 | bne .LBB0_4 54 | @ BB#3: @ %if.end 55 | bl __cxa_end_catch 56 | mov r0, #0 57 | pop {r11, lr} 58 | bx lr 59 | .LBB0_4: @ %if.then 60 | bl abort 61 | .p2align 2 62 | @ BB#5: 63 | .LCPI0_0: 64 | .long _ZTIi 65 | .Lfunc_end0: 66 | 67 | .size main, .Lfunc_end0-main 68 | .globl __gxx_personality_v0 69 | .personality __gxx_personality_v0 70 | .handlerdata 71 | .p2align 2 72 | GCC_except_table0: 73 | .Lexception0: 74 | .byte 255 @ @LPStart Encoding = omit 75 | .byte 0x90 @ @TType Encoding = indirect | pcrel 76 | .asciz "\257\200" @ @TType base offset 77 | .byte 3 @ Call site Encoding = udata4 78 | .byte 39 @ Call site table length 79 | .long .Lfunc_begin0-.Lfunc_begin0 @ >> Call Site 1 << 80 | .long .Ltmp0-.Lfunc_begin0 @ Call between .Lfunc_begin0 and .Ltmp0 81 | .long 0 @ has no landing pad 82 | .byte 0 @ On action: cleanup 83 | .long .Ltmp0-.Lfunc_begin0 @ >> Call Site 2 << 84 | .long .Ltmp1-.Ltmp0 @ Call between .Ltmp0 and .Ltmp1 85 | .long .Ltmp2-.Lfunc_begin0 @ jumps to .Ltmp2 86 | .byte 1 @ On action: 1 87 | .long .Ltmp1-.Lfunc_begin0 @ >> Call Site 3 << 88 | .long .Lfunc_end0-.Ltmp1 @ Call between .Ltmp1 and .Lfunc_end0 89 | .long 0 @ has no landing pad 90 | .byte 0 @ On action: cleanup 91 | .byte 1 @ >> Action Record 1 << 92 | @ Catch TypeInfo 1 93 | .byte 0 @ No further actions 94 | @ >> Catch TypeInfos << 95 | .long _ZTIi(target2) @ TypeInfo 1 96 | .p2align 2 97 | .fnend 98 | -------------------------------------------------------------------------------- /test/noexception1.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- noexception1.pass.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03 10 | // REQUIRES: libcxxabi-no-exceptions 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // namespace __cxxabiv1 { 18 | // void __cxa_increment_exception_refcount(void *thrown_object) throw(); 19 | // } 20 | 21 | unsigned gCounter = 0; 22 | 23 | void my_terminate() { exit(0); } 24 | 25 | int main () 26 | { 27 | // should not call std::terminate() 28 | __cxxabiv1::__cxa_increment_exception_refcount(nullptr); 29 | 30 | std::set_terminate(my_terminate); 31 | 32 | // should call std::terminate() 33 | __cxxabiv1::__cxa_increment_exception_refcount((void*) &gCounter); 34 | assert(false); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /test/noexception2.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- noexception2.pass.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03 10 | // REQUIRES: libcxxabi-no-exceptions 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // namespace __cxxabiv1 { 18 | // void __cxa_decrement_exception_refcount(void *thrown_object) throw(); 19 | // } 20 | 21 | unsigned gCounter = 0; 22 | 23 | void my_terminate() { exit(0); } 24 | 25 | int main () 26 | { 27 | // should not call std::terminate() 28 | __cxxabiv1::__cxa_decrement_exception_refcount(nullptr); 29 | 30 | std::set_terminate(my_terminate); 31 | 32 | // should call std::terminate() 33 | __cxxabiv1::__cxa_decrement_exception_refcount((void*) &gCounter); 34 | assert(false); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /test/noexception3.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- noexception3.pass.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03 10 | // REQUIRES: libcxxabi-no-exceptions 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // namespace __cxxabiv1 { 18 | // void __cxa_rethrow_primary_exception(void* thrown_object); 19 | // } 20 | 21 | unsigned gCounter = 0; 22 | 23 | void my_terminate() { exit(0); } 24 | 25 | int main () 26 | { 27 | // should not call std::terminate() 28 | __cxxabiv1::__cxa_rethrow_primary_exception(nullptr); 29 | 30 | std::set_terminate(my_terminate); 31 | 32 | // should call std::terminate() 33 | __cxxabiv1::__cxa_rethrow_primary_exception((void*) &gCounter); 34 | assert(false); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /test/noexception4.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- noexception4.pass.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // REQUIRES: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | // namespace __cxxabiv1 { 16 | // void *__cxa_current_primary_exception() throw(); 17 | // extern bool __cxa_uncaught_exception () throw(); 18 | // extern unsigned int __cxa_uncaught_exceptions() throw(); 19 | // } 20 | 21 | int main () 22 | { 23 | // Trivially 24 | assert(nullptr == __cxxabiv1::__cxa_current_primary_exception()); 25 | assert(!__cxxabiv1::__cxa_uncaught_exception()); 26 | assert(0 == __cxxabiv1::__cxa_uncaught_exceptions()); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /test/support/timer.hpp: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===//// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===//// 8 | 9 | #ifndef TIMER_HPP 10 | #define TIMER_HPP 11 | 12 | // Define LIBCXXABI_NO_TIMER to disable testing with a timer. 13 | #ifndef LIBCXXABI_NO_TIMER 14 | 15 | #include 16 | #include 17 | 18 | class timer 19 | { 20 | typedef std::chrono::high_resolution_clock Clock; 21 | typedef Clock::time_point TimePoint; 22 | typedef std::chrono::microseconds MicroSeconds; 23 | public: 24 | timer() : m_start(Clock::now()) {} 25 | 26 | timer(timer const &) = delete; 27 | timer & operator=(timer const &) = delete; 28 | 29 | ~timer() 30 | { 31 | using std::chrono::duration_cast; 32 | TimePoint end = Clock::now(); 33 | MicroSeconds us = duration_cast(end - m_start); 34 | std::cout << us.count() << " microseconds\n"; 35 | } 36 | 37 | private: 38 | TimePoint m_start; 39 | }; 40 | 41 | #else /* LIBCXXABI_NO_TIMER */ 42 | 43 | class timer 44 | { 45 | public: 46 | timer() {} 47 | timer(timer const &) = delete; 48 | timer & operator=(timer const &) = delete; 49 | ~timer() {} 50 | }; 51 | 52 | #endif /* LIBCXXABI_NO_TIMER */ 53 | 54 | #endif /* TIMER_HPP */ 55 | -------------------------------------------------------------------------------- /test/test_aux_runtime.pass.cpp: -------------------------------------------------------------------------------- 1 | //===-------------------------- test_aux_runtime.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | 14 | // Test taken from 5.2.8.2 15 | // When typeid is applied to a glvalue expression whose type is a polymorphic 16 | // class type, (10.3), the result refers to a std::type_info object 17 | // representing the type of the most derived object (1.8) (that is, the 18 | // dynamic type) to which the glvalue refers. If the glvalue expression is 19 | // obtained by applying the unary * operator to a pointer(68) and the pointer 20 | // is a null pointer value (4.10), the typeid expression throws the 21 | // std::bad_typeid exception (18.7.3). 22 | // 23 | // 68) If p is an expression of pointer type, then *p, (*p), *(p), 24 | // ((*p)), *((p)), and so on all meet this requirement. 25 | bool bad_typeid_test () { 26 | class A { virtual void f() {}}; 27 | class B { virtual void g() {}}; 28 | 29 | B *bp = NULL; 30 | try {bool b = typeid(*bp) == typeid (A); ((void)b); } 31 | catch ( const std::bad_typeid &) { return true; } 32 | return false; 33 | } 34 | 35 | 36 | // The value of a failed cast to pointer type is the null pointer value of 37 | // the required result type. A failed cast to reference type throws 38 | // std::bad_cast (18.7.2). 39 | bool bad_cast_test () { 40 | class A { virtual void f() {}}; 41 | class B { virtual void g() {}}; 42 | class D : public virtual A, private B {}; 43 | 44 | D d; 45 | B *bp = (B*)&d; // cast needed to break protection 46 | try { D &dr = dynamic_cast (*bp); ((void)dr); } 47 | catch ( const std::bad_cast & ) { return true; } 48 | return false; 49 | } 50 | 51 | int main ( ) { 52 | int ret_val = 0; 53 | 54 | if ( !bad_typeid_test ()) { 55 | std::cerr << "TypeID test failed!" << std::endl; 56 | ret_val = 1; 57 | } 58 | 59 | if ( !bad_cast_test ()) { 60 | std::cerr << "Bad cast test failed!" << std::endl; 61 | ret_val = 1; 62 | } 63 | 64 | return ret_val; 65 | } 66 | -------------------------------------------------------------------------------- /test/test_aux_runtime_op_array_new.pass.cpp: -------------------------------------------------------------------------------- 1 | //===-------------------------- test_aux_runtime_op_array_new.cpp ---------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | 14 | // If the expression passed to operator new[] would result in an overflow, the 15 | // allocation function is not called, and a std::bad_array_new_length exception 16 | // is thrown instead (5.3.4p7). 17 | bool bad_array_new_length_test() { 18 | try { 19 | // We test this directly because Clang does not currently codegen the 20 | // correct call to __cxa_bad_array_new_length, so this test would result 21 | // in passing -1 to ::operator new[], which would then throw a 22 | // std::bad_alloc, causing the test to fail. 23 | __cxxabiv1::__cxa_throw_bad_array_new_length(); 24 | } catch ( const std::bad_array_new_length &banl ) { 25 | return true; 26 | } 27 | return false; 28 | } 29 | 30 | int main() { 31 | int ret_val = 0; 32 | 33 | if ( !bad_array_new_length_test ()) { 34 | std::cerr << "Bad array new length test failed!" << std::endl; 35 | ret_val = 1; 36 | } 37 | 38 | return ret_val; 39 | } 40 | -------------------------------------------------------------------------------- /test/test_exception_address_alignment.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | // UNSUPPORTED: c++98, c++03 11 | 12 | // The system unwind.h on OS X provides an incorrectly aligned _Unwind_Exception 13 | // type. That causes these tests to fail. This XFAIL is my best attempt at 14 | // working around this failure. 15 | // XFAIL: darwin && libcxxabi-has-system-unwinder 16 | 17 | // Test that the address of the exception object is properly aligned as required 18 | // by the relevant ABI 19 | 20 | #include 21 | #include 22 | #include <__cxxabi_config.h> 23 | 24 | #include 25 | 26 | struct __attribute__((aligned)) AlignedType {}; 27 | 28 | // EHABI : 8-byte aligned 29 | // Itanium: Largest supported alignment for the system 30 | #if defined(_LIBCXXABI_ARM_EHABI) 31 | # define EXPECTED_ALIGNMENT 8 32 | #else 33 | # define EXPECTED_ALIGNMENT alignof(AlignedType) 34 | #endif 35 | 36 | static_assert(alignof(_Unwind_Exception) == EXPECTED_ALIGNMENT, 37 | "_Unwind_Exception is incorrectly aligned. This test is expected to fail"); 38 | 39 | struct MinAligned { }; 40 | static_assert(alignof(MinAligned) == 1 && sizeof(MinAligned) == 1, ""); 41 | 42 | int main() { 43 | for (int i=0; i < 10; ++i) { 44 | try { 45 | throw MinAligned{}; 46 | } catch (MinAligned const& ref) { 47 | assert(reinterpret_cast(&ref) % EXPECTED_ALIGNMENT == 0); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/test_exception_storage.pass.cpp: -------------------------------------------------------------------------------- 1 | //===-------------------- test_exception_storage.cpp ----------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include 10 | #include 11 | #include 12 | #include <__threading_support> 13 | #include 14 | 15 | #include "../src/cxa_exception.hpp" 16 | 17 | typedef __cxxabiv1::__cxa_eh_globals globals_t ; 18 | 19 | void *thread_code (void *parm) { 20 | size_t *result = (size_t *) parm; 21 | globals_t *glob1, *glob2; 22 | 23 | glob1 = __cxxabiv1::__cxa_get_globals (); 24 | if ( NULL == glob1 ) 25 | std::cerr << "Got null result from __cxa_get_globals" << std::endl; 26 | 27 | glob2 = __cxxabiv1::__cxa_get_globals_fast (); 28 | if ( glob1 != glob2 ) 29 | std::cerr << "Got different globals!" << std::endl; 30 | 31 | *result = (size_t) glob1; 32 | sleep ( 1 ); 33 | return parm; 34 | } 35 | 36 | #ifndef _LIBCXXABI_HAS_NO_THREADS 37 | #define NUMTHREADS 10 38 | size_t thread_globals [ NUMTHREADS ] = { 0 }; 39 | std::__libcpp_thread_t threads [ NUMTHREADS ]; 40 | #endif 41 | 42 | int main () { 43 | int retVal = 0; 44 | 45 | #ifndef _LIBCXXABI_HAS_NO_THREADS 46 | // Make the threads, let them run, and wait for them to finish 47 | for ( int i = 0; i < NUMTHREADS; ++i ) 48 | std::__libcpp_thread_create ( threads + i, thread_code, (void *) (thread_globals + i)); 49 | for ( int i = 0; i < NUMTHREADS; ++i ) 50 | std::__libcpp_thread_join ( &threads [ i ] ); 51 | 52 | for ( int i = 0; i < NUMTHREADS; ++i ) 53 | if ( 0 == thread_globals [ i ] ) { 54 | std::cerr << "Thread #" << i << " had a zero global" << std::endl; 55 | retVal = 1; 56 | } 57 | 58 | std::sort ( thread_globals, thread_globals + NUMTHREADS ); 59 | for ( int i = 1; i < NUMTHREADS; ++i ) 60 | if ( thread_globals [ i - 1 ] == thread_globals [ i ] ) { 61 | std::cerr << "Duplicate thread globals (" << i-1 << " and " << i << ")" << std::endl; 62 | retVal = 2; 63 | } 64 | #else // _LIBCXXABI_HAS_NO_THREADS 65 | size_t thread_globals; 66 | // Check that __cxa_get_globals() is not NULL. 67 | if (thread_code(&thread_globals) == 0) { 68 | retVal = 1; 69 | } 70 | #endif // !_LIBCXXABI_HAS_NO_THREADS 71 | return retVal; 72 | } 73 | -------------------------------------------------------------------------------- /test/test_guard.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------------- test_guard.cpp -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | #include "cxxabi.h" 10 | 11 | #include 12 | 13 | #ifndef _LIBCXXABI_HAS_NO_THREADS 14 | #include 15 | #endif 16 | 17 | // Ensure that we initialize each variable once and only once. 18 | namespace test1 { 19 | static int run_count = 0; 20 | int increment() { 21 | ++run_count; 22 | return 0; 23 | } 24 | void helper() { 25 | static int a = increment(); 26 | ((void)a); 27 | } 28 | void test() { 29 | static int a = increment(); ((void)a); 30 | assert(run_count == 1); 31 | static int b = increment(); ((void)b); 32 | assert(run_count == 2); 33 | helper(); 34 | assert(run_count == 3); 35 | helper(); 36 | assert(run_count == 3); 37 | } 38 | } 39 | 40 | // When initialization fails, ensure that we try to initialize it again next 41 | // time. 42 | namespace test2 { 43 | #ifndef LIBCXXABI_HAS_NO_EXCEPTIONS 44 | static int run_count = 0; 45 | int increment() { 46 | ++run_count; 47 | throw 0; 48 | } 49 | void helper() { 50 | try { 51 | static int a = increment(); 52 | assert(false); 53 | ((void)a); 54 | } catch (...) {} 55 | } 56 | void test() { 57 | helper(); 58 | assert(run_count == 1); 59 | helper(); 60 | assert(run_count == 2); 61 | } 62 | #else 63 | void test() {} 64 | #endif 65 | } 66 | 67 | // Check that we can initialize a second value while initializing a first. 68 | namespace test3 { 69 | int zero() { 70 | return 0; 71 | } 72 | 73 | int one() { 74 | static int b = zero(); ((void)b); 75 | return 0; 76 | } 77 | 78 | void test() { 79 | static int a = one(); ((void)a); 80 | } 81 | } 82 | 83 | #ifndef _LIBCXXABI_HAS_NO_THREADS 84 | // A simple thread test of two threads racing to initialize a variable. This 85 | // isn't guaranteed to catch any particular threading problems. 86 | namespace test4 { 87 | static int run_count = 0; 88 | int increment() { 89 | ++run_count; 90 | return 0; 91 | } 92 | 93 | void helper() { 94 | static int a = increment(); ((void)a); 95 | } 96 | 97 | void test() { 98 | std::thread t1(helper), t2(helper); 99 | t1.join(); 100 | t2.join(); 101 | assert(run_count == 1); 102 | } 103 | } 104 | 105 | // Check that we don't re-initialize a static variable even when it's 106 | // encountered from two different threads. 107 | namespace test5 { 108 | static int run_count = 0; 109 | int zero() { 110 | ++run_count; 111 | return 0; 112 | } 113 | 114 | int one() { 115 | static int b = zero(); ((void)b); 116 | return 0; 117 | } 118 | 119 | void another_helper() { 120 | static int a = one(); ((void)a); 121 | } 122 | 123 | void helper() { 124 | static int a = one(); ((void)a); 125 | std::thread t(another_helper); 126 | t.join(); 127 | } 128 | 129 | void test() { 130 | std::thread t(helper); 131 | t.join(); 132 | assert(run_count == 1); 133 | } 134 | } 135 | #endif /* _LIBCXXABI_HAS_NO_THREADS */ 136 | 137 | int main() 138 | { 139 | test1::test(); 140 | test2::test(); 141 | test3::test(); 142 | #ifndef _LIBCXXABI_HAS_NO_THREADS 143 | test4::test(); 144 | test5::test(); 145 | #endif 146 | } 147 | -------------------------------------------------------------------------------- /test/test_vector2.pass.cpp: -------------------------------------------------------------------------------- 1 | //===--------------------------- test_vector2.cpp -------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include "cxxabi.h" 12 | 13 | #include 14 | #include 15 | 16 | void my_terminate () { exit ( 0 ); } 17 | 18 | // Wrapper routines 19 | void *my_alloc2 ( size_t sz ) { 20 | void *p = std::malloc ( sz ); 21 | // std::printf ( "Allocated %ld bytes at %lx\n", sz, (unsigned long) p ); 22 | return p; 23 | } 24 | 25 | void my_dealloc2 ( void *p ) { 26 | // std::printf ( "Freeing %lx\n", (unsigned long) p ); 27 | std::free ( p ); 28 | } 29 | 30 | void my_dealloc3 ( void *p, size_t ) { 31 | // std::printf ( "Freeing %lx (size %ld)\n", (unsigned long) p, sz ); 32 | std::free ( p ); 33 | } 34 | 35 | void my_construct ( void *) { 36 | // std::printf ( "Constructing %lx\n", (unsigned long) p ); 37 | } 38 | 39 | void my_destruct ( void *) { 40 | // std::printf ( "Destructing %lx\n", (unsigned long) p ); 41 | } 42 | 43 | int gCounter; 44 | void count_construct ( void * ) { ++gCounter; } 45 | void count_destruct ( void * ) { --gCounter; } 46 | 47 | 48 | int gConstructorCounter; 49 | int gConstructorThrowTarget; 50 | int gDestructorCounter; 51 | int gDestructorThrowTarget; 52 | void throw_construct ( void * ) { if ( gConstructorCounter == gConstructorThrowTarget ) throw 1; ++gConstructorCounter; } 53 | void throw_destruct ( void * ) { if ( ++gDestructorCounter == gDestructorThrowTarget ) throw 2; } 54 | 55 | struct vec_on_stack { 56 | void *storage; 57 | vec_on_stack () : storage ( __cxxabiv1::__cxa_vec_new ( 10, 40, 8, throw_construct, throw_destruct )) {} 58 | ~vec_on_stack () { __cxxabiv1::__cxa_vec_delete ( storage, 40, 8, throw_destruct ); } 59 | }; 60 | 61 | 62 | // Make sure the constructors and destructors are matched 63 | void test_exception_in_destructor ( ) { 64 | 65 | // Try throwing from a destructor while unwinding the stack -- should abort 66 | gConstructorCounter = gDestructorCounter = 0; 67 | gConstructorThrowTarget = -1; 68 | gDestructorThrowTarget = 5; 69 | try { 70 | vec_on_stack v; 71 | throw 3; 72 | } 73 | catch ( int i ) {} 74 | 75 | std::cerr << "should never get here" << std::endl; 76 | } 77 | 78 | 79 | 80 | int main () { 81 | std::set_terminate ( my_terminate ); 82 | test_exception_in_destructor (); 83 | return 1; // we failed if we get here 84 | } 85 | -------------------------------------------------------------------------------- /test/test_vector3.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- test_vector3.cpp ---------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include "cxxabi.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | // use dtors instead of try/catch 21 | namespace test1 { 22 | struct B { 23 | ~B() { 24 | printf("should not be run\n"); 25 | exit(10); 26 | } 27 | }; 28 | 29 | struct A { 30 | ~A() 31 | #if __has_feature(cxx_noexcept) 32 | noexcept(false) 33 | #endif 34 | { 35 | B b; 36 | throw 0; 37 | } 38 | }; 39 | } // test1 40 | 41 | void my_terminate() { exit(0); } 42 | 43 | template 44 | void destroy(void* v) 45 | { 46 | T* t = static_cast(v); 47 | t->~T(); 48 | } 49 | 50 | int main() 51 | { 52 | std::set_terminate(my_terminate); 53 | { 54 | typedef test1::A Array[10]; 55 | Array a[10]; // calls _cxa_vec_dtor 56 | __cxxabiv1::__cxa_vec_dtor(a, 10, sizeof(test1::A), destroy); 57 | assert(false); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /test/testit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | #===------------------------------ testit ----------------------------------===# 3 | # 4 | # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 | # See https://llvm.org/LICENSE.txt for license information. 6 | # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 | # 8 | #===------------------------------------------------------------------------===# 9 | 10 | if [ -z "$CC" ] 11 | then 12 | CC=clang++ 13 | fi 14 | 15 | if [ -z "$OPTIONS" ] 16 | then 17 | OPTIONS="-std=c++0x -stdlib=libc++" 18 | fi 19 | 20 | case $TRIPLE in 21 | *-*-mingw* | *-*-cygwin* | *-*-win*) 22 | TEST_EXE=test.exe 23 | ;; 24 | *) 25 | TEST_EXE=a.out 26 | ;; 27 | esac 28 | 29 | FAIL=0 30 | PASS=0 31 | UNIMPLEMENTED=0 32 | IMPLEMENTED_FAIL=0 33 | IMPLEMENTED_PASS=0 34 | 35 | afunc() 36 | { 37 | fail=0 38 | pass=0 39 | if (ls *.fail.cpp > /dev/null 2>&1) 40 | then 41 | for FILE in $(ls *.fail.cpp); do 42 | if $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o ./$TEST_EXE > /dev/null 2>&1 43 | then 44 | rm ./$TEST_EXE 45 | echo "$FILE should not compile" 46 | fail=$(($fail + 1)) 47 | else 48 | pass=$(($pass + 1)) 49 | fi 50 | done 51 | fi 52 | 53 | if (ls *.cpp > /dev/null 2>&1) 54 | then 55 | for FILE in $(ls *.pass.cpp); do 56 | if $CC $OPTIONS $HEADER_INCLUDE $SOURCE_LIB $FILE $LIBS -o ./$TEST_EXE 57 | then 58 | if ./$TEST_EXE 59 | then 60 | rm ./$TEST_EXE 61 | pass=$(($pass + 1)) 62 | else 63 | echo "$FILE failed at run time" 64 | fail=$(($fail + 1)) 65 | rm ./$TEST_EXE 66 | fi 67 | else 68 | echo "$FILE failed to compile" 69 | fail=$(($fail + 1)) 70 | fi 71 | done 72 | fi 73 | 74 | if [ $fail -gt 0 ] 75 | then 76 | echo "failed $fail tests in `pwd`" 77 | IMPLEMENTED_FAIL=$(($IMPLEMENTED_FAIL + 1)) 78 | fi 79 | if [ $pass -gt 0 ] 80 | then 81 | echo "passed $pass tests in `pwd`" 82 | if [ $fail -eq 0 ] 83 | then 84 | IMPLEMENTED_PASS=$(($IMPLEMENTED_PASS + 1)) 85 | fi 86 | fi 87 | if [ $fail -eq 0 -a $pass -eq 0 ] 88 | then 89 | echo "not implemented: `pwd`" 90 | UNIMPLEMENTED=$(($UNIMPLEMENTED + 1)) 91 | fi 92 | 93 | FAIL=$(($FAIL + $fail)) 94 | PASS=$(($PASS + $pass)) 95 | 96 | for FILE in * 97 | do 98 | if [ -d "$FILE" ]; 99 | then 100 | cd $FILE 101 | afunc 102 | cd .. 103 | fi 104 | done 105 | } 106 | 107 | afunc 108 | 109 | echo "****************************************************" 110 | echo "Results for `pwd`:" 111 | echo "using `$CC --version`" 112 | echo "with $OPTIONS $HEADER_INCLUDE $SOURCE_LIB" 113 | echo "----------------------------------------------------" 114 | echo "sections without tests : $UNIMPLEMENTED" 115 | echo "sections with failures : $IMPLEMENTED_FAIL" 116 | echo "sections without failures: $IMPLEMENTED_PASS" 117 | echo " + ----" 118 | echo "total number of sections : $(($UNIMPLEMENTED+$IMPLEMENTED_FAIL+$IMPLEMENTED_PASS))" 119 | echo "----------------------------------------------------" 120 | echo "number of tests failed : $FAIL" 121 | echo "number of tests passed : $PASS" 122 | echo " + ----" 123 | echo "total number of tests : $(($FAIL+$PASS))" 124 | echo "****************************************************" 125 | 126 | exit $FAIL 127 | -------------------------------------------------------------------------------- /test/thread_local_destruction_order.pass.cpp: -------------------------------------------------------------------------------- 1 | //===-------------- thread_local_destruction_order.pass.cpp ---------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // Darwin TLV finalization routines fail when creating a thread-local variable 10 | // in the destructor for another thread-local variable: 11 | // http://lists.llvm.org/pipermail/cfe-dev/2016-November/051376.html 12 | // XFAIL: darwin 13 | // UNSUPPORTED: c++98, c++03 14 | // UNSUPPORTED: libcxxabi-no-threads 15 | 16 | #include 17 | #include 18 | 19 | int seq = 0; 20 | 21 | class OrderChecker { 22 | public: 23 | explicit OrderChecker(int n) : n_{n} { } 24 | 25 | ~OrderChecker() { 26 | assert(seq++ == n_); 27 | } 28 | 29 | private: 30 | int n_; 31 | }; 32 | 33 | template 34 | class CreatesThreadLocalInDestructor { 35 | public: 36 | ~CreatesThreadLocalInDestructor() { 37 | thread_local OrderChecker checker{ID}; 38 | } 39 | }; 40 | 41 | OrderChecker global{7}; 42 | 43 | void thread_fn() { 44 | static OrderChecker fn_static{5}; 45 | thread_local CreatesThreadLocalInDestructor<2> creates_tl2; 46 | thread_local OrderChecker fn_thread_local{1}; 47 | thread_local CreatesThreadLocalInDestructor<0> creates_tl0; 48 | } 49 | 50 | int main() { 51 | static OrderChecker fn_static{6}; 52 | 53 | std::thread{thread_fn}.join(); 54 | assert(seq == 3); 55 | 56 | thread_local OrderChecker fn_thread_local{4}; 57 | thread_local CreatesThreadLocalInDestructor<3> creates_tl; 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /test/uncaught_exceptions.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------- uncaught_exceptions.pass.cpp ---------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | // namespace __cxxabiv1 { 16 | // extern bool __cxa_uncaught_exception () throw(); 17 | // extern unsigned int __cxa_uncaught_exceptions() throw(); 18 | // } 19 | 20 | struct A { 21 | ~A() { assert( __cxxabiv1::__cxa_uncaught_exception()); } 22 | }; 23 | 24 | struct B { 25 | B(unsigned cnt) : data_(cnt) {} 26 | ~B() { assert( data_ == __cxxabiv1::__cxa_uncaught_exceptions()); } 27 | unsigned data_; 28 | }; 29 | 30 | int main () 31 | { 32 | try { A a; throw 3; assert (false); } 33 | catch (int) {} 34 | 35 | try { B b(1); throw 3; assert (false); } 36 | catch (int) {} 37 | } 38 | -------------------------------------------------------------------------------- /test/unittest_demangle.pass.cpp: -------------------------------------------------------------------------------- 1 | //===----------------------- unittest_demangle.cpp ------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: c++98, c++03 10 | 11 | #include "../src/cxa_demangle.cpp" 12 | 13 | using namespace __cxxabiv1; 14 | 15 | void testPODSmallVector() { 16 | { // {push/pop}_back 17 | PODSmallVector PSV; 18 | PSV.push_back(0); 19 | PSV.push_back(1); 20 | PSV.push_back(2); 21 | PSV.push_back(3); 22 | for (int i = 0; i < 4; ++i) 23 | assert(PSV[i] == i); 24 | PSV.pop_back(); 25 | for (int i = 0; i < 3; ++i) 26 | assert(PSV[i] == i); 27 | PSV.pop_back(); 28 | PSV.pop_back(); 29 | assert(!PSV.empty() && PSV.size() == 1); 30 | PSV.pop_back(); 31 | assert(PSV.empty() && PSV.size() == 0); 32 | } 33 | 34 | { 35 | PODSmallVector PSV1; 36 | PSV1.push_back(1); 37 | PSV1.push_back(2); 38 | PSV1.push_back(3); 39 | 40 | PODSmallVector PSV2; 41 | std::swap(PSV1, PSV2); 42 | assert(PSV1.size() == 0); 43 | assert(PSV2.size() == 3); 44 | int i = 1; 45 | for (int x : PSV2) { 46 | assert(x == i); 47 | ++i; 48 | } 49 | assert(i == 4); 50 | std::swap(PSV1, PSV2); 51 | assert(PSV1.size() == 3); 52 | assert(PSV2.size() == 0); 53 | i = 1; 54 | for (int x : PSV1) { 55 | assert(x == i); 56 | ++i; 57 | } 58 | assert(i == 4); 59 | } 60 | 61 | { 62 | PODSmallVector PSV1; 63 | PODSmallVector PSV2; 64 | PSV1.push_back(0); 65 | PSV1.push_back(1); 66 | PSV1.push_back(2); 67 | assert(PSV1.size() == 3); 68 | assert(PSV2.size() == 0); 69 | std::swap(PSV1, PSV2); 70 | assert(PSV1.size() == 0); 71 | assert(PSV2.size() == 3); 72 | int i = 0; 73 | for (int x : PSV2) { 74 | assert(x == i); 75 | ++i; 76 | } 77 | for (int x : PSV1) { 78 | assert(false); 79 | (void)x; 80 | } 81 | } 82 | } 83 | 84 | int main() { 85 | testPODSmallVector(); 86 | } 87 | -------------------------------------------------------------------------------- /test/unwind_01.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- unwind_01.cpp ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | 11 | #include 12 | 13 | #if defined(__GNUC__) 14 | #pragma GCC diagnostic ignored "-Wunreachable-code" 15 | #endif 16 | 17 | struct A 18 | { 19 | static int count; 20 | int id_; 21 | A() : id_(++count) {} 22 | ~A() {assert(id_ == count--);} 23 | 24 | private: 25 | A(const A&); 26 | A& operator=(const A&); 27 | }; 28 | 29 | int A::count = 0; 30 | 31 | struct B 32 | { 33 | static int count; 34 | int id_; 35 | B() : id_(++count) {} 36 | ~B() {assert(id_ == count--);} 37 | 38 | private: 39 | B(const B&); 40 | B& operator=(const B&); 41 | }; 42 | 43 | int B::count = 0; 44 | 45 | struct C 46 | { 47 | static int count; 48 | int id_; 49 | C() : id_(++count) {} 50 | ~C() {assert(id_ == count--);} 51 | 52 | private: 53 | C(const C&); 54 | C& operator=(const C&); 55 | }; 56 | 57 | int C::count = 0; 58 | 59 | void f2() 60 | { 61 | C c; 62 | A a; 63 | throw 55; 64 | B b; 65 | } 66 | 67 | void f1() 68 | { 69 | A a; 70 | B b; 71 | f2(); 72 | C c; 73 | } 74 | 75 | int main() 76 | { 77 | try 78 | { 79 | f1(); 80 | assert(false); 81 | } 82 | catch (int* i) 83 | { 84 | assert(false); 85 | } 86 | catch (long i) 87 | { 88 | assert(false); 89 | } 90 | catch (int i) 91 | { 92 | assert(i == 55); 93 | } 94 | catch (...) 95 | { 96 | assert(false); 97 | } 98 | assert(A::count == 0); 99 | assert(B::count == 0); 100 | assert(C::count == 0); 101 | } 102 | -------------------------------------------------------------------------------- /test/unwind_02.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- unwind_02.cpp ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | // REQUIRES: c++98 || c++03 || c++11 || c++14 11 | 12 | #include 13 | 14 | #if defined(__GNUC__) 15 | #pragma GCC diagnostic ignored "-Wunreachable-code" 16 | #endif 17 | 18 | struct A 19 | { 20 | static int count; 21 | int id_; 22 | A() : id_(++count) {} 23 | ~A() {assert(id_ == count--);} 24 | 25 | private: 26 | A(const A&); 27 | A& operator=(const A&); 28 | }; 29 | 30 | int A::count = 0; 31 | 32 | struct B 33 | { 34 | static int count; 35 | int id_; 36 | B() : id_(++count) {} 37 | ~B() {assert(id_ == count--);} 38 | 39 | private: 40 | B(const B&); 41 | B& operator=(const B&); 42 | }; 43 | 44 | int B::count = 0; 45 | 46 | struct C 47 | { 48 | static int count; 49 | int id_; 50 | C() : id_(++count) {} 51 | ~C() {assert(id_ == count--);} 52 | 53 | private: 54 | C(const C&); 55 | C& operator=(const C&); 56 | }; 57 | 58 | int C::count = 0; 59 | 60 | void f2() 61 | { 62 | C c; 63 | A a; 64 | throw 55; 65 | B b; 66 | } 67 | 68 | void f1() throw (long, char, int, double) 69 | { 70 | A a; 71 | B b; 72 | f2(); 73 | C c; 74 | } 75 | 76 | int main() 77 | { 78 | try 79 | { 80 | f1(); 81 | assert(false); 82 | } 83 | catch (int* i) 84 | { 85 | assert(false); 86 | } 87 | catch (long i) 88 | { 89 | assert(false); 90 | } 91 | catch (int i) 92 | { 93 | assert(i == 55); 94 | } 95 | catch (...) 96 | { 97 | assert(false); 98 | } 99 | assert(A::count == 0); 100 | assert(B::count == 0); 101 | assert(C::count == 0); 102 | } 103 | -------------------------------------------------------------------------------- /test/unwind_03.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- unwind_03.cpp ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | // REQUIRES: c++98 || c++03 || c++11 || c++14 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #if defined(__GNUC__) 17 | #pragma GCC diagnostic ignored "-Wunreachable-code" 18 | #endif 19 | 20 | struct A 21 | { 22 | static int count; 23 | int id_; 24 | A() : id_(++count) {} 25 | ~A() {assert(id_ == count--);} 26 | 27 | private: 28 | A(const A&); 29 | A& operator=(const A&); 30 | }; 31 | 32 | int A::count = 0; 33 | 34 | struct B 35 | { 36 | static int count; 37 | int id_; 38 | B() : id_(++count) {} 39 | ~B() {assert(id_ == count--);} 40 | 41 | private: 42 | B(const B&); 43 | B& operator=(const B&); 44 | }; 45 | 46 | int B::count = 0; 47 | 48 | struct C 49 | { 50 | static int count; 51 | int id_; 52 | C() : id_(++count) {} 53 | ~C() {assert(id_ == count--);} 54 | 55 | private: 56 | C(const C&); 57 | C& operator=(const C&); 58 | }; 59 | 60 | int C::count = 0; 61 | 62 | void f2() 63 | { 64 | C c; 65 | A a; 66 | throw 55; 67 | B b; 68 | } 69 | 70 | void f1() throw (long, char, double) 71 | { 72 | A a; 73 | B b; 74 | f2(); 75 | C c; 76 | } 77 | 78 | void u_handler() 79 | { 80 | exit(0); 81 | } 82 | 83 | int main() 84 | { 85 | std::set_unexpected(u_handler); 86 | try 87 | { 88 | f1(); 89 | assert(false); 90 | } 91 | catch (int* i) 92 | { 93 | assert(false); 94 | } 95 | catch (long i) 96 | { 97 | assert(false); 98 | } 99 | catch (int i) 100 | { 101 | assert(i == 55); 102 | } 103 | catch (...) 104 | { 105 | assert(false); 106 | } 107 | assert(false); 108 | } 109 | -------------------------------------------------------------------------------- /test/unwind_04.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- unwind_04.cpp ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | // REQUIRES: c++98 || c++03 || c++11 || c++14 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #if defined(__GNUC__) 17 | #pragma GCC diagnostic ignored "-Wunreachable-code" 18 | #endif 19 | 20 | struct A 21 | { 22 | static int count; 23 | int id_; 24 | A() : id_(++count) {} 25 | ~A() {assert(id_ == count--);} 26 | 27 | private: 28 | A(const A&); 29 | A& operator=(const A&); 30 | }; 31 | 32 | int A::count = 0; 33 | 34 | struct B 35 | { 36 | static int count; 37 | int id_; 38 | B() : id_(++count) {} 39 | ~B() {assert(id_ == count--);} 40 | 41 | private: 42 | B(const B&); 43 | B& operator=(const B&); 44 | }; 45 | 46 | int B::count = 0; 47 | 48 | struct C 49 | { 50 | static int count; 51 | int id_; 52 | C() : id_(++count) {} 53 | ~C() {assert(id_ == count--);} 54 | 55 | private: 56 | C(const C&); 57 | C& operator=(const C&); 58 | }; 59 | 60 | int C::count = 0; 61 | 62 | void f2() 63 | { 64 | C c; 65 | A a; 66 | throw 55; 67 | B b; 68 | } 69 | 70 | void f1() throw (long, char, double) 71 | { 72 | A a; 73 | B b; 74 | f2(); 75 | C c; 76 | } 77 | 78 | void u_handler() 79 | { 80 | throw 'a'; 81 | } 82 | 83 | int main() 84 | { 85 | std::set_unexpected(u_handler); 86 | try 87 | { 88 | f1(); 89 | assert(false); 90 | } 91 | catch (int* i) 92 | { 93 | assert(false); 94 | } 95 | catch (long i) 96 | { 97 | assert(false); 98 | } 99 | catch (int i) 100 | { 101 | assert(false); 102 | } 103 | catch (char c) 104 | { 105 | assert(c == 'a'); 106 | } 107 | catch (...) 108 | { 109 | assert(false); 110 | } 111 | assert(A::count == 0); 112 | assert(B::count == 0); 113 | assert(C::count == 0); 114 | } 115 | -------------------------------------------------------------------------------- /test/unwind_05.pass.cpp: -------------------------------------------------------------------------------- 1 | //===------------------------- unwind_05.cpp ------------------------------===// 2 | // 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 | // See https://llvm.org/LICENSE.txt for license information. 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 | // 7 | //===----------------------------------------------------------------------===// 8 | 9 | // UNSUPPORTED: libcxxabi-no-exceptions 10 | // REQUIRES: c++98 || c++03 || c++11 || c++14 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #if defined(__GNUC__) 17 | #pragma GCC diagnostic ignored "-Wunreachable-code" 18 | #endif 19 | 20 | struct A 21 | { 22 | static int count; 23 | int id_; 24 | A() : id_(++count) {} 25 | ~A() {assert(id_ == count--);} 26 | 27 | private: 28 | A(const A&); 29 | A& operator=(const A&); 30 | }; 31 | 32 | int A::count = 0; 33 | 34 | struct B 35 | { 36 | static int count; 37 | int id_; 38 | B() : id_(++count) {} 39 | ~B() {assert(id_ == count--);} 40 | 41 | private: 42 | B(const B&); 43 | B& operator=(const B&); 44 | }; 45 | 46 | int B::count = 0; 47 | 48 | struct C 49 | { 50 | static int count; 51 | int id_; 52 | C() : id_(++count) {} 53 | ~C() {assert(id_ == count--);} 54 | 55 | private: 56 | C(const C&); 57 | C& operator=(const C&); 58 | }; 59 | 60 | int C::count = 0; 61 | 62 | void f2() 63 | { 64 | C c; 65 | A a; 66 | throw 55; 67 | B b; 68 | } 69 | 70 | void f1() throw (long, char, double, std::bad_exception) 71 | { 72 | A a; 73 | B b; 74 | f2(); 75 | C c; 76 | } 77 | 78 | void u_handler() 79 | { 80 | throw; 81 | } 82 | 83 | int main() 84 | { 85 | std::set_unexpected(u_handler); 86 | try 87 | { 88 | f1(); 89 | assert(false); 90 | } 91 | catch (int* i) 92 | { 93 | assert(false); 94 | } 95 | catch (long i) 96 | { 97 | assert(false); 98 | } 99 | catch (int i) 100 | { 101 | assert(false); 102 | } 103 | catch (char c) 104 | { 105 | assert(false); 106 | } 107 | catch (const std::bad_exception& e) 108 | { 109 | assert(true); 110 | } 111 | catch (...) 112 | { 113 | assert(false); 114 | } 115 | assert(A::count == 0); 116 | assert(B::count == 0); 117 | assert(C::count == 0); 118 | } 119 | -------------------------------------------------------------------------------- /www/content.css: -------------------------------------------------------------------------------- 1 | html { margin: 0px; } body { margin: 8px; } 2 | 3 | html, body { 4 | padding:0px; 5 | font-size:small; font-family:"Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, Helvetica, sans-serif; background-color: #fff; color: #222; 6 | line-height:1.5; 7 | } 8 | 9 | h1, h2, h3, tt { color: #000 } 10 | 11 | h1 { padding-top:0px; margin-top:0px;} 12 | h2 { color:#333333; padding-top:0.5em; } 13 | h3 { padding-top: 0.5em; margin-bottom: -0.25em; color:#2d58b7} 14 | li { padding-bottom: 0.5em; } 15 | ul { padding-left:1.5em; } 16 | 17 | /* Slides */ 18 | IMG.img_slide { 19 | display: block; 20 | margin-left: auto; 21 | margin-right: auto 22 | } 23 | 24 | .itemTitle { color:#2d58b7 } 25 | 26 | /* Tables */ 27 | tr { vertical-align:top } 28 | -------------------------------------------------------------------------------- /www/menu.css: -------------------------------------------------------------------------------- 1 | /***************/ 2 | /* page layout */ 3 | /***************/ 4 | 5 | [id=menu] { 6 | position:fixed; 7 | width:25ex; 8 | } 9 | [id=content] { 10 | /* ***** EDIT THIS VALUE IF CONTENT OVERLAPS MENU ***** */ 11 | position:absolute; 12 | left:29ex; 13 | padding-right:4ex; 14 | } 15 | 16 | /**************/ 17 | /* menu style */ 18 | /**************/ 19 | 20 | #menu .submenu { 21 | padding-top:1em; 22 | display:block; 23 | } 24 | 25 | #menu label { 26 | display:block; 27 | font-weight: bold; 28 | text-align: center; 29 | background-color: rgb(192,192,192); 30 | } 31 | #menu a { 32 | padding:0 .2em; 33 | display:block; 34 | text-align: center; 35 | background-color: rgb(235,235,235); 36 | } 37 | #menu a:visited { 38 | color:rgb(100,50,100); 39 | } 40 | --------------------------------------------------------------------------------