From 3cd1885209ca64c5a14589e289cba584aa7b8de4 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 18 Dec 2018 20:49:24 +0300 Subject: [PATCH 01/14] Reorganized code and made __cxa_get_globals signature closer to the original. This should resolve gcc errors caused by mismatch of the return types of aur declaration of __cxa_get_globals and the original in cxxabi.h. Fixes https://github.com/boostorg/core/issues/45. --- include/boost/core/uncaught_exceptions.hpp | 61 +++++++++++++--------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/include/boost/core/uncaught_exceptions.hpp b/include/boost/core/uncaught_exceptions.hpp index b971ffb..6dbdce1 100644 --- a/include/boost/core/uncaught_exceptions.hpp +++ b/include/boost/core/uncaught_exceptions.hpp @@ -26,14 +26,16 @@ #pragma once #endif -namespace boost { +// Visual Studio 14 supports N4152 std::uncaught_exceptions() +#if (defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411) || \ + (defined(_MSC_VER) && _MSC_VER >= 1900) +#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS +#endif -namespace core { - -namespace detail { +#if !defined(BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS) // cxxabi.h availability macro -#if defined(__has_include) && (!defined(BOOST_GCC) || (__GNUC__ + 0) >= 5) +#if defined(__has_include) && (!defined(BOOST_GCC) || (__GNUC__ >= 5)) # if __has_include() # define BOOST_CORE_HAS_CXXABI_H # endif @@ -41,33 +43,44 @@ namespace detail { # define BOOST_CORE_HAS_CXXABI_H #endif -#if defined(__cpp_lib_uncaught_exceptions) && __cpp_lib_uncaught_exceptions >= 201411 -#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS -#elif defined(BOOST_CORE_HAS_CXXABI_H) +#if defined(BOOST_CORE_HAS_CXXABI_H) // MinGW GCC 4.4 seem to not work the same way the newer GCC versions do. As a result, __cxa_get_globals based implementation will always return 0. // Just disable it for now and fall back to std::uncaught_exception(). #if !defined(__MINGW32__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) -// Only GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there #define BOOST_CORE_HAS_CXA_GET_GLOBALS -extern "C" void* __cxa_get_globals(); -#endif -#elif defined(_MSC_VER) -#if _MSC_VER >= 1900 -// Visual Studio 14 supports N4152 std::uncaught_exceptions() -#define BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS -#elif _MSC_VER >= 1400 -#define BOOST_CORE_HAS_GETPTD -extern "C" void* _getptd(); -#endif +#include +// Only GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 +namespace __cxxabiv1 { +struct __cxa_eh_globals; +extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __attribute__((__const__)); +} // namespace __cxxabiv1 +#endif // defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 #endif +#endif // defined(BOOST_CORE_HAS_CXXABI_H) +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#define BOOST_CORE_HAS_GETPTD +namespace boost { +namespace core { +namespace detail { +extern "C" void* _getptd(); } // namespace detail +} // namespace core +} // namespace boost +#endif // defined(_MSC_VER) && _MSC_VER >= 1400 + +#endif // !defined(BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS) #if !defined(BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS) && !defined(BOOST_CORE_HAS_CXA_GET_GLOBALS) && !defined(BOOST_CORE_HAS_GETPTD) //! This macro is defined when `uncaught_exceptions` is not guaranteed to return values greater than 1 if multiple exceptions are pending #define BOOST_CORE_UNCAUGHT_EXCEPTIONS_EMULATED #endif +namespace boost { + +namespace core { + //! Returns the number of currently pending exceptions inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT { @@ -76,7 +89,7 @@ inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT return static_cast< unsigned int >(std::uncaught_exceptions()); #elif defined(BOOST_CORE_HAS_CXA_GET_GLOBALS) // Tested on {clang 3.2,GCC 3.5.6,GCC 4.1.2,GCC 4.4.6,GCC 4.4.7}x{x32,x64} - return *(reinterpret_cast< const unsigned int* >(static_cast< const char* >(boost::core::detail::__cxa_get_globals()) + sizeof(void*))); // __cxa_eh_globals::uncaughtExceptions, x32 offset - 0x4, x64 - 0x8 + return *(reinterpret_cast< const unsigned int* >(reinterpret_cast< const char* >(::abi::__cxa_get_globals()) + sizeof(void*))); // __cxa_eh_globals::uncaughtExceptions, x32 offset - 0x4, x64 - 0x8 #elif defined(BOOST_CORE_HAS_GETPTD) // MSVC specific. Tested on {MSVC2005SP1,MSVC2008SP1,MSVC2010SP1,MSVC2012}x{x32,x64}. return *(reinterpret_cast< const unsigned int* >(static_cast< const char* >(boost::core::detail::_getptd()) + (sizeof(void*) == 8 ? 0x100 : 0x90))); // _tiddata::_ProcessingThrow, x32 offset - 0x90, x64 - 0x100 @@ -86,13 +99,13 @@ inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT #endif } +} // namespace core + +} // namespace boost + #undef BOOST_CORE_HAS_CXXABI_H #undef BOOST_CORE_HAS_CXA_GET_GLOBALS #undef BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS #undef BOOST_CORE_HAS_GETPTD -} // namespace core - -} // namespace boost - #endif // BOOST_CORE_UNCAUGHT_EXCEPTIONS_HPP_INCLUDED_ From 2b60d044ac6bfd2297e2f28ad74e0dc376b4bf9f Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 18 Dec 2018 21:53:49 +0300 Subject: [PATCH 02/14] Added tools/boost_install and libs/headers manual init to CI jobs. --- .travis.yml | 2 ++ appveyor.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index b3e509d..85c8433 100644 --- a/.travis.yml +++ b/.travis.yml @@ -258,12 +258,14 @@ install: - cd .. - git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root - cd boost-root + - git submodule init libs/headers - git submodule init libs/assert - git submodule init libs/config - git submodule init libs/predef - git submodule init libs/static_assert - git submodule init libs/type_traits - git submodule init tools/build + - git submodule init tools/boost_install - git submodule update - cp -r $TRAVIS_BUILD_DIR/* libs/core - ./bootstrap.sh diff --git a/appveyor.yml b/appveyor.yml index 0ba2b61..a007db8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -55,12 +55,14 @@ install: - cd .. - git clone -b %BOOST_BRANCH% https://github.com/boostorg/boost.git boost-root - cd boost-root + - git submodule init libs/headers - git submodule init libs/assert - git submodule init libs/config - git submodule init libs/predef - git submodule init libs/static_assert - git submodule init libs/type_traits - git submodule init tools/build + - git submodule init tools/boost_install - git submodule update - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\core - cmd /c bootstrap From 83ea633d096a1be5347d9ba40bcd2c0de92f9b99 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 18 Dec 2018 22:19:50 +0300 Subject: [PATCH 03/14] Use multiple jobs to checkout submodules in CI. --- .travis.yml | 2 +- appveyor.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85c8433..27bd1b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -266,7 +266,7 @@ install: - git submodule init libs/type_traits - git submodule init tools/build - git submodule init tools/boost_install - - git submodule update + - git submodule update --jobs 4 - cp -r $TRAVIS_BUILD_DIR/* libs/core - ./bootstrap.sh - ./b2 headers diff --git a/appveyor.yml b/appveyor.yml index a007db8..3664a15 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -63,7 +63,7 @@ install: - git submodule init libs/type_traits - git submodule init tools/build - git submodule init tools/boost_install - - git submodule update + - git submodule update --jobs 4 - xcopy /s /e /q %APPVEYOR_BUILD_FOLDER% libs\core - cmd /c bootstrap - b2 headers From bbcd5b8f5c0f15547a7d89eb1ef8772f2f270dfc Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Thu, 3 Jan 2019 23:05:17 +0300 Subject: [PATCH 04/14] Use the actual number of logical CPUs for the number of CI build/test jobs. --- .travis.yml | 3 ++- appveyor.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 27bd1b9..350bf13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -274,7 +274,8 @@ install: script: - |- echo "using $TOOLSET : : $COMPILER ;" > ~/user-config.jam - - ./b2 -j 3 libs/core/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} + - BUILD_JOBS=`(nproc || sysctl -n hw.ncpu) 2> /dev/null` + - ./b2 -j $BUILD_JOBS libs/core/test toolset=$TOOLSET cxxstd=$CXXSTD variant=debug,release ${UBSAN:+cxxflags=-fsanitize=undefined cxxflags=-fno-sanitize-recover=undefined linkflags=-fsanitize=undefined define=UBSAN=1 debug-symbols=on} ${LINKFLAGS:+linkflags=$LINKFLAGS} notifications: email: diff --git a/appveyor.yml b/appveyor.yml index 3664a15..14c8b42 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -73,4 +73,4 @@ build: off test_script: - PATH=%ADDPATH%%PATH% - if not "%CXXSTD%" == "" set CXXSTD=cxxstd=%CXXSTD% - - b2 -j 3 libs/core/test toolset=%TOOLSET% %CXXSTD% + - b2 -j %NUMBER_OF_PROCESSORS% libs/core/test toolset=%TOOLSET% %CXXSTD% From 2574ae8a0cd4c0b62dbb04fc0babfd64f506da93 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Thu, 3 Jan 2019 23:47:43 +0300 Subject: [PATCH 05/14] Made git branch selection less obscure and more POSIX shell conforming. --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 350bf13..2834f8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -254,7 +254,8 @@ matrix: env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z install: - - BOOST_BRANCH=develop && [ "$TRAVIS_BRANCH" == "master" ] && BOOST_BRANCH=master || true + - BOOST_BRANCH=develop + - if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi - cd .. - git clone -b $BOOST_BRANCH https://github.com/boostorg/boost.git boost-root - cd boost-root From 245297ab85c6a870650753c395f7394d514b1ac7 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 6 Jan 2019 04:43:47 +0200 Subject: [PATCH 06/14] Add test/cmake_subdir_test --- .travis.yml | 9 +++++++++ test/cmake_subdir_test/CMakeLists.txt | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/cmake_subdir_test/CMakeLists.txt diff --git a/.travis.yml b/.travis.yml index 2834f8b..d87eaea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -253,6 +253,15 @@ matrix: compiler: clang++ env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z + - os: linux + compiler: g++ + env: CMAKE_SUBDIR_TEST=1 + script: + - cd libs/core/test/cmake_subdir_test && mkdir __build__ && cd __build__ + - cmake .. + - cmake --build . + - cmake --build . --target check + install: - BOOST_BRANCH=develop - if [ "$TRAVIS_BRANCH" = "master" ]; then BOOST_BRANCH=master; fi diff --git a/test/cmake_subdir_test/CMakeLists.txt b/test/cmake_subdir_test/CMakeLists.txt new file mode 100644 index 0000000..ae24a60 --- /dev/null +++ b/test/cmake_subdir_test/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright 2018, 2019 Peter Dimov +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.5) + +project(cmake_subdir_test LANGUAGES CXX) + +add_subdirectory(../.. boostorg/core) +add_subdirectory(../../../assert boostorg/assert) +add_subdirectory(../../../config boostorg/config) + +add_executable(quick ../quick.cpp) +target_link_libraries(quick Boost::core) + +enable_testing() +add_test(quick quick) + +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $) From 6f3e6254e7f4980673ec0e2d3accb3252b629c0a Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 6 Jan 2019 21:29:15 +0300 Subject: [PATCH 07/14] Only declare __cxa_get_globals on MinGW gcc < 4.7, where it's needed. This should work around differences between the function signatures on other platforms, like FreeBSD, for example. --- include/boost/core/uncaught_exceptions.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/core/uncaught_exceptions.hpp b/include/boost/core/uncaught_exceptions.hpp index 6dbdce1..686487c 100644 --- a/include/boost/core/uncaught_exceptions.hpp +++ b/include/boost/core/uncaught_exceptions.hpp @@ -47,15 +47,15 @@ // MinGW GCC 4.4 seem to not work the same way the newer GCC versions do. As a result, __cxa_get_globals based implementation will always return 0. // Just disable it for now and fall back to std::uncaught_exception(). #if !defined(__MINGW32__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) -#define BOOST_CORE_HAS_CXA_GET_GLOBALS #include -// Only GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there -#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 +#define BOOST_CORE_HAS_CXA_GET_GLOBALS +// Only MinGW GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there +#if defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 namespace __cxxabiv1 { struct __cxa_eh_globals; extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __attribute__((__const__)); } // namespace __cxxabiv1 -#endif // defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 +#endif // defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 #endif #endif // defined(BOOST_CORE_HAS_CXXABI_H) From cdcc50a4554a4ea4fc9f4a9b83611e71fc793222 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Mon, 7 Jan 2019 02:14:31 +0300 Subject: [PATCH 08/14] Added an implementation for uncaught_exceptions for libc++abi. This should fix compilation errors due to missing declaration of __cxa_get_globals when compiled against libc++ on Linux. --- include/boost/core/uncaught_exceptions.hpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/include/boost/core/uncaught_exceptions.hpp b/include/boost/core/uncaught_exceptions.hpp index 686487c..fa9d25e 100644 --- a/include/boost/core/uncaught_exceptions.hpp +++ b/include/boost/core/uncaught_exceptions.hpp @@ -46,16 +46,23 @@ #if defined(BOOST_CORE_HAS_CXXABI_H) // MinGW GCC 4.4 seem to not work the same way the newer GCC versions do. As a result, __cxa_get_globals based implementation will always return 0. // Just disable it for now and fall back to std::uncaught_exception(). -#if !defined(__MINGW32__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))) +#if !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405)) #include + +// On Linux with clang and libc++, there is a version of cxxabi.h from libc++-abi that doesn't declare __cxa_get_globals, but provides __cxa_uncaught_exceptions. +#if defined(_LIBCPPABI_VERSION) +#define BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS +#else #define BOOST_CORE_HAS_CXA_GET_GLOBALS -// Only MinGW GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there -#if defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 +// On MinGW only GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there. +// Note that at least on FreeBSD 11, cxxabi.h declares __cxa_get_globals with a different exception specification, so we can't declare the function unconditionally. +#if (defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) namespace __cxxabiv1 { struct __cxa_eh_globals; extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __attribute__((__const__)); } // namespace __cxxabiv1 -#endif // defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407 +#endif +#endif #endif #endif // defined(BOOST_CORE_HAS_CXXABI_H) @@ -87,6 +94,9 @@ inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT #if defined(BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS) // C++17 implementation return static_cast< unsigned int >(std::uncaught_exceptions()); +#elif defined(BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS) + // libc++abi extension + return static_cast< unsigned int >(abi::__cxa_uncaught_exceptions()); #elif defined(BOOST_CORE_HAS_CXA_GET_GLOBALS) // Tested on {clang 3.2,GCC 3.5.6,GCC 4.1.2,GCC 4.4.6,GCC 4.4.7}x{x32,x64} return *(reinterpret_cast< const unsigned int* >(reinterpret_cast< const char* >(::abi::__cxa_get_globals()) + sizeof(void*))); // __cxa_eh_globals::uncaughtExceptions, x32 offset - 0x4, x64 - 0x8 @@ -105,6 +115,7 @@ inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT #undef BOOST_CORE_HAS_CXXABI_H #undef BOOST_CORE_HAS_CXA_GET_GLOBALS +#undef BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS #undef BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS #undef BOOST_CORE_HAS_GETPTD From 9f9da9dc9b49624ec6cd9237ec79aca604983c4a Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Mon, 7 Jan 2019 13:34:52 +0300 Subject: [PATCH 09/14] Limit __cxa_uncaught_exceptions to only since libc++abi 1002 and later. --- include/boost/core/uncaught_exceptions.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boost/core/uncaught_exceptions.hpp b/include/boost/core/uncaught_exceptions.hpp index fa9d25e..c48aca2 100644 --- a/include/boost/core/uncaught_exceptions.hpp +++ b/include/boost/core/uncaught_exceptions.hpp @@ -50,13 +50,14 @@ #include // On Linux with clang and libc++, there is a version of cxxabi.h from libc++-abi that doesn't declare __cxa_get_globals, but provides __cxa_uncaught_exceptions. -#if defined(_LIBCPPABI_VERSION) +// The function only appeared in version 1002. +#if defined(_LIBCPPABI_VERSION) && _LIBCPPABI_VERSION >= 1002 #define BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS #else #define BOOST_CORE_HAS_CXA_GET_GLOBALS // On MinGW only GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there. // Note that at least on FreeBSD 11, cxxabi.h declares __cxa_get_globals with a different exception specification, so we can't declare the function unconditionally. -#if (defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) +#if (defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || defined(_LIBCPPABI_VERSION) namespace __cxxabiv1 { struct __cxa_eh_globals; extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __attribute__((__const__)); From dea6b0415724850f9b76368183572dd71a65034a Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 8 Jan 2019 00:23:09 +0300 Subject: [PATCH 10/14] Added workarounds for gcc < 4.7 on Linux and OpenBSD. Apparently, gcc < 4.7 on Linux also don't have __cxa_get_globals declaration in cxxabi.h. Declare the function ourselves. Also, on OpenBSD it seems there is no declaration either, and on that platform the function implementation has no exception specification, like on FreeBSD. Add a declaration of that platform. Lastly, changed __cxa_get_globals and _getptd-based implementations to avoid violating strict aliasing rules. This is still formally UB to access structure fields like we do, but this is one less reason to cause miscompilation or compiler warnings. --- include/boost/core/uncaught_exceptions.hpp | 30 +++++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/include/boost/core/uncaught_exceptions.hpp b/include/boost/core/uncaught_exceptions.hpp index c48aca2..8df3acc 100644 --- a/include/boost/core/uncaught_exceptions.hpp +++ b/include/boost/core/uncaught_exceptions.hpp @@ -49,25 +49,37 @@ #if !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405)) #include -// On Linux with clang and libc++, there is a version of cxxabi.h from libc++-abi that doesn't declare __cxa_get_globals, but provides __cxa_uncaught_exceptions. -// The function only appeared in version 1002. +// On Linux with clang and libc++, there is a version of cxxabi.h from libc++abi that doesn't declare __cxa_get_globals, but provides __cxa_uncaught_exceptions. +// The function only appeared in version 1002 of the library. #if defined(_LIBCPPABI_VERSION) && _LIBCPPABI_VERSION >= 1002 #define BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS #else +#include #define BOOST_CORE_HAS_CXA_GET_GLOBALS -// On MinGW only GCC 4.7 declares __cxa_get_globals() in cxxabi.h, older compilers do not expose this function but it's there. +// At least on MinGW and Linux, only GCC since 4.7 declares __cxa_get_globals() in cxxabi.h. Older versions of GCC do not expose this function but it's there. +// On OpenBSD, it seems, the declaration is also missing. // Note that at least on FreeBSD 11, cxxabi.h declares __cxa_get_globals with a different exception specification, so we can't declare the function unconditionally. -#if (defined(__MINGW32__) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || defined(_LIBCPPABI_VERSION) +#if !defined(__FreeBSD__) && \ + ( \ + (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || \ + defined(__OpenBSD__) || \ + defined(_LIBCPPABI_VERSION) \ + ) namespace __cxxabiv1 { struct __cxa_eh_globals; +#if defined(__OpenBSD__) +extern "C" __cxa_eh_globals* __cxa_get_globals(); +#else extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __attribute__((__const__)); +#endif } // namespace __cxxabiv1 #endif #endif -#endif +#endif // !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405)) #endif // defined(BOOST_CORE_HAS_CXXABI_H) #if defined(_MSC_VER) && _MSC_VER >= 1400 +#include #define BOOST_CORE_HAS_GETPTD namespace boost { namespace core { @@ -100,10 +112,14 @@ inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT return static_cast< unsigned int >(abi::__cxa_uncaught_exceptions()); #elif defined(BOOST_CORE_HAS_CXA_GET_GLOBALS) // Tested on {clang 3.2,GCC 3.5.6,GCC 4.1.2,GCC 4.4.6,GCC 4.4.7}x{x32,x64} - return *(reinterpret_cast< const unsigned int* >(reinterpret_cast< const char* >(::abi::__cxa_get_globals()) + sizeof(void*))); // __cxa_eh_globals::uncaughtExceptions, x32 offset - 0x4, x64 - 0x8 + unsigned int count; + std::memcpy(&count, reinterpret_cast< const unsigned char* >(::abi::__cxa_get_globals()) + sizeof(void*), sizeof(count)); // __cxa_eh_globals::uncaughtExceptions, x32 offset - 0x4, x64 - 0x8 + return count; #elif defined(BOOST_CORE_HAS_GETPTD) // MSVC specific. Tested on {MSVC2005SP1,MSVC2008SP1,MSVC2010SP1,MSVC2012}x{x32,x64}. - return *(reinterpret_cast< const unsigned int* >(static_cast< const char* >(boost::core::detail::_getptd()) + (sizeof(void*) == 8 ? 0x100 : 0x90))); // _tiddata::_ProcessingThrow, x32 offset - 0x90, x64 - 0x100 + unsigned int count; + std::memcpy(&count, static_cast< const unsigned char* >(boost::core::detail::_getptd()) + (sizeof(void*) == 8u ? 0x100 : 0x90), sizeof(count)); // _tiddata::_ProcessingThrow, x32 offset - 0x90, x64 - 0x100 + return count; #else // Portable C++03 implementation. Does not allow to detect multiple nested exceptions. return static_cast< unsigned int >(std::uncaught_exception()); From e3629dd1c17198156ac2df6c950e0b972c2eaea5 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 8 Jan 2019 00:29:53 +0300 Subject: [PATCH 11/14] Added libc++abi-dev package installation, changed OS X image to xcode10.1. This is in attempt to debug/work around strange issues in CI with cxxabi.h provided by libc++abi-dev. The header declares __cxa_uncaught_exceptions function, but on linking stage the function is missing. The current theory is that the header and the libc++abi library do not match on CI machines for some reason, and this commit tries to mitigate or verify that. --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index d87eaea..9a70cb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -240,6 +240,7 @@ matrix: apt: packages: - libc++-dev + - libc++abi-dev - os: linux compiler: clang++-libc++ @@ -248,10 +249,12 @@ matrix: apt: packages: - libc++-dev + - libc++abi-dev - os: osx compiler: clang++ env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z + osx_image: xcode10.1 - os: linux compiler: g++ From bf932b49084ba4e590c90fefeed3df896985ecf8 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 8 Jan 2019 04:17:24 +0300 Subject: [PATCH 12/14] Removed the use of __cxa_uncaught_exceptions. Travis CI shows linking errors on Linux and OS X when __cxa_uncaught_exceptions is used to implement uncaught_exceptions. There's probably some library missing, which should be linked in implicitly by the compiler, or the library indeed does not export the symbol. In any case, __cxa_get_globals-based implementation should provide the same effect. --- include/boost/core/uncaught_exceptions.hpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/include/boost/core/uncaught_exceptions.hpp b/include/boost/core/uncaught_exceptions.hpp index 8df3acc..b32c0da 100644 --- a/include/boost/core/uncaught_exceptions.hpp +++ b/include/boost/core/uncaught_exceptions.hpp @@ -48,17 +48,14 @@ // Just disable it for now and fall back to std::uncaught_exception(). #if !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405)) #include - -// On Linux with clang and libc++, there is a version of cxxabi.h from libc++abi that doesn't declare __cxa_get_globals, but provides __cxa_uncaught_exceptions. -// The function only appeared in version 1002 of the library. -#if defined(_LIBCPPABI_VERSION) && _LIBCPPABI_VERSION >= 1002 -#define BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS -#else #include #define BOOST_CORE_HAS_CXA_GET_GLOBALS // At least on MinGW and Linux, only GCC since 4.7 declares __cxa_get_globals() in cxxabi.h. Older versions of GCC do not expose this function but it's there. // On OpenBSD, it seems, the declaration is also missing. // Note that at least on FreeBSD 11, cxxabi.h declares __cxa_get_globals with a different exception specification, so we can't declare the function unconditionally. +// On Linux with clang and libc++ and on OS X, there is a version of cxxabi.h from libc++abi that doesn't declare __cxa_get_globals, but provides __cxa_uncaught_exceptions. +// The function only appeared in version _LIBCPPABI_VERSION >= 1002 of the library. Unfortunately, there are linking errors about undefined reference to __cxa_uncaught_exceptions, +// so we avoid using it and forward-declare __cxa_get_globals instead. #if !defined(__FreeBSD__) && \ ( \ (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || \ @@ -74,7 +71,6 @@ extern "C" __cxa_eh_globals* __cxa_get_globals() BOOST_NOEXCEPT_OR_NOTHROW __att #endif } // namespace __cxxabiv1 #endif -#endif #endif // !(defined(__MINGW32__) && (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 405)) #endif // defined(BOOST_CORE_HAS_CXXABI_H) @@ -107,9 +103,6 @@ inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT #if defined(BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS) // C++17 implementation return static_cast< unsigned int >(std::uncaught_exceptions()); -#elif defined(BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS) - // libc++abi extension - return static_cast< unsigned int >(abi::__cxa_uncaught_exceptions()); #elif defined(BOOST_CORE_HAS_CXA_GET_GLOBALS) // Tested on {clang 3.2,GCC 3.5.6,GCC 4.1.2,GCC 4.4.6,GCC 4.4.7}x{x32,x64} unsigned int count; @@ -132,7 +125,6 @@ inline unsigned int uncaught_exceptions() BOOST_NOEXCEPT #undef BOOST_CORE_HAS_CXXABI_H #undef BOOST_CORE_HAS_CXA_GET_GLOBALS -#undef BOOST_CORE_HAS_CXA_UNCAUGHT_EXCEPTIONS #undef BOOST_CORE_HAS_UNCAUGHT_EXCEPTIONS #undef BOOST_CORE_HAS_GETPTD From 7d70451b49ec79b0db0f939f6ef17a1b96fb7cb4 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 8 Jan 2019 04:47:51 +0300 Subject: [PATCH 13/14] Updated the comment about __cxa_uncaught_exceptions. --- include/boost/core/uncaught_exceptions.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/core/uncaught_exceptions.hpp b/include/boost/core/uncaught_exceptions.hpp index b32c0da..29b1c7a 100644 --- a/include/boost/core/uncaught_exceptions.hpp +++ b/include/boost/core/uncaught_exceptions.hpp @@ -54,8 +54,8 @@ // On OpenBSD, it seems, the declaration is also missing. // Note that at least on FreeBSD 11, cxxabi.h declares __cxa_get_globals with a different exception specification, so we can't declare the function unconditionally. // On Linux with clang and libc++ and on OS X, there is a version of cxxabi.h from libc++abi that doesn't declare __cxa_get_globals, but provides __cxa_uncaught_exceptions. -// The function only appeared in version _LIBCPPABI_VERSION >= 1002 of the library. Unfortunately, there are linking errors about undefined reference to __cxa_uncaught_exceptions, -// so we avoid using it and forward-declare __cxa_get_globals instead. +// The function only appeared in version _LIBCPPABI_VERSION >= 1002 of the library. Unfortunately, there are linking errors about undefined reference to __cxa_uncaught_exceptions +// on Ubuntu Trusty and OS X, so we avoid using it and forward-declare __cxa_get_globals instead. #if !defined(__FreeBSD__) && \ ( \ (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) < 407) || \ From 9db11ce55446a1a3d0ca754fbc4d57744418f22b Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 13 Jan 2019 04:26:10 +0200 Subject: [PATCH 14/14] Add more xcode configurations to Travis --- .travis.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9a70cb9..ec5adb5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -251,6 +251,21 @@ matrix: - libc++-dev - libc++abi-dev + - os: osx + compiler: clang++ + env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z + osx_image: xcode7.3 + + - os: osx + compiler: clang++ + env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z + osx_image: xcode8.3 + + - os: osx + compiler: clang++ + env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z + osx_image: xcode9.4 + - os: osx compiler: clang++ env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z