From b648c611ed60d37eb9e29f3c10da227b5d1811e1 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Wed, 9 Jun 2021 09:41:27 -0400 Subject: [PATCH] [libc++] Fix libc++ build with assertions enabled This fixes http://llvm.org/PR50534. This is another take on D103960 which is less disruptive. Differential Revision: https://reviews.llvm.org/D103964 --- libcxx/cmake/caches/Generic-assertions.cmake | 1 + libcxx/include/__config | 44 ++++++++++++---------------- libcxx/src/string.cpp | 6 ++-- libcxx/utils/ci/buildkite-pipeline.yml | 12 ++++++++ libcxx/utils/ci/run-buildbot | 8 +++++ 5 files changed, 43 insertions(+), 28 deletions(-) create mode 100644 libcxx/cmake/caches/Generic-assertions.cmake diff --git a/libcxx/cmake/caches/Generic-assertions.cmake b/libcxx/cmake/caches/Generic-assertions.cmake new file mode 100644 index 0000000..e8ef72a --- /dev/null +++ b/libcxx/cmake/caches/Generic-assertions.cmake @@ -0,0 +1 @@ +set(LIBCXX_ENABLE_ASSERTIONS ON CACHE BOOL "") diff --git a/libcxx/include/__config b/libcxx/include/__config index 82ec762..1f966ad 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -911,33 +911,27 @@ typedef unsigned int char32_t; # error Supported values for _LIBCPP_DEBUG are 0 and 1 #endif -// _LIBCPP_DEBUG_LEVEL is always defined to one of [0, 1, 2] at this point -#if _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE) -# define _LIBCPP_EXTERN_TEMPLATE(...) -#endif - -#ifdef _LIBCPP_DISABLE_EXTERN_TEMPLATE -# define _LIBCPP_EXTERN_TEMPLATE(...) -# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) -#endif - -#ifndef _LIBCPP_EXTERN_TEMPLATE -#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; -#endif - -// When the Debug mode is enabled, we disable extern declarations because we -// don't want to use the functions compiled in the library, which might not -// have had the debug mode enabled when built. However, some extern declarations -// need to be used, because code correctness depends on it (several instances -// in the ). Those special declarations are declared with -// _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled even -// when the debug mode is enabled. -#ifndef _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE -# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__; +// Libc++ allows disabling extern template instantiation declarations by +// means of users defining _LIBCPP_DISABLE_EXTERN_TEMPLATE. +// +// Furthermore, when the Debug mode is enabled, we disable extern declarations +// when building user code because we don't want to use the functions compiled +// in the library, which might not have had the debug mode enabled when built. +// However, some extern declarations need to be used, because code correctness +// depends on it (several instances in ). Those special declarations +// are declared with _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE, which is enabled +// even when the debug mode is enabled. +#if defined(_LIBCPP_DISABLE_EXTERN_TEMPLATE) +# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */ +# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) /* nothing */ +#elif _LIBCPP_DEBUG_LEVEL >= 1 && !defined(_LIBCPP_BUILDING_LIBRARY) +# define _LIBCPP_EXTERN_TEMPLATE(...) /* nothing */ +# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__; +#else +# define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__; +# define _LIBCPP_EXTERN_TEMPLATE_EVEN_IN_DEBUG_MODE(...) extern template __VA_ARGS__; #endif -#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; - #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_LIBCPP_MSVCRT_LIKE) || \ defined(__sun__) || defined(__NetBSD__) || defined(__CloudABI__) #define _LIBCPP_LOCALE__L_EXTENSIONS 1 diff --git a/libcxx/src/string.cpp b/libcxx/src/string.cpp index 5105594..63b81d6 100644 --- a/libcxx/src/string.cpp +++ b/libcxx/src/string.cpp @@ -20,6 +20,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD template class _LIBCPP_CLASS_TEMPLATE_INSTANTIATION_VIS __basic_string_common; +#define _LIBCPP_EXTERN_TEMPLATE_DEFINE(...) template __VA_ARGS__; #ifdef _LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char) _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t) @@ -27,10 +28,9 @@ _LIBCPP_STRING_UNSTABLE_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wch _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, char) _LIBCPP_STRING_V1_EXTERN_TEMPLATE_LIST(_LIBCPP_EXTERN_TEMPLATE_DEFINE, wchar_t) #endif +#undef _LIBCPP_EXTERN_TEMPLATE_DEFINE -template - string - operator+, allocator >(char const*, string const&); +template string operator+, allocator >(char const*, string const&); namespace { diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml index 58272b6..7daaab1 100644 --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -186,6 +186,18 @@ steps: - exit_status: -1 # Agent was lost limit: 2 + - label: "Assertions enabled" + command: "libcxx/utils/ci/run-buildbot generic-assertions" + artifact_paths: + - "**/test-results.xml" + - "**/*.abilist" + agents: + queue: "libcxx-builders" + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + - label: "Debug iterators" command: "libcxx/utils/ci/run-buildbot generic-debug-iterators" artifact_paths: diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot index 9395ec6..f25e696 100755 --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -233,6 +233,14 @@ generic-cxx2b) check-cxx-cxxabi check-abi-list ;; +generic-assertions) + export CC=clang + export CXX=clang++ + clean + generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Generic-assertions.cmake" + check-cxx-cxxabi + check-abi-list +;; generic-debug-iterators) export CC=clang-tot export CXX=clang++-tot -- 2.7.4