diff --git a/libcxx/include/__config b/libcxx/include/__config --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -221,7 +221,12 @@ #endif #if defined(_LIBCPP_ABI_MICROSOFT) && !defined(_LIBCPP_NO_VCRUNTIME) -# define _LIBCPP_ABI_VCRUNTIME +# define _LIBCPP_ABI_VCRUNTIME +# if defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0 +# define _LIBCPP_NO_EXCEPTIONS +# else +# define _LIBCPP_ABI_VCRUNTIME_EXCEPTION +# endif #endif // Need to detect which libc we're using if we're on Linux. diff --git a/libcxx/include/exception b/libcxx/include/exception --- a/libcxx/include/exception +++ b/libcxx/include/exception @@ -84,7 +84,7 @@ #include #include -#if defined(_LIBCPP_ABI_VCRUNTIME) +#if defined(_LIBCPP_ABI_VCRUNTIME_EXCEPTION) #include #endif @@ -95,7 +95,7 @@ namespace std // purposefully not using versioning namespace { -#if !defined(_LIBCPP_ABI_VCRUNTIME) +#if !defined(_LIBCPP_ABI_VCRUNTIME_EXCEPTION) class _LIBCPP_EXCEPTION_ABI exception { public: diff --git a/libcxx/include/stdexcept b/libcxx/include/stdexcept --- a/libcxx/include/stdexcept +++ b/libcxx/include/stdexcept @@ -52,7 +52,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION class _LIBCPP_HIDDEN __libcpp_refstring { const char* __imp_; @@ -76,7 +76,7 @@ class _LIBCPP_EXCEPTION_ABI logic_error : public exception { -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION private: _VSTD::__libcpp_refstring __imp_; public: @@ -99,7 +99,7 @@ class _LIBCPP_EXCEPTION_ABI runtime_error : public exception { -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION private: _VSTD::__libcpp_refstring __imp_; public: @@ -126,7 +126,7 @@ _LIBCPP_INLINE_VISIBILITY explicit domain_error(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit domain_error(const char* __s) : logic_error(__s) {} -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION domain_error(const domain_error&) _NOEXCEPT = default; virtual ~domain_error() _NOEXCEPT; #endif @@ -139,7 +139,7 @@ _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit invalid_argument(const char* __s) : logic_error(__s) {} -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION invalid_argument(const invalid_argument&) _NOEXCEPT = default; virtual ~invalid_argument() _NOEXCEPT; #endif @@ -151,7 +151,7 @@ public: _LIBCPP_INLINE_VISIBILITY explicit length_error(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit length_error(const char* __s) : logic_error(__s) {} -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION length_error(const length_error&) _NOEXCEPT = default; virtual ~length_error() _NOEXCEPT; #endif @@ -164,7 +164,7 @@ _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const string& __s) : logic_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit out_of_range(const char* __s) : logic_error(__s) {} -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION out_of_range(const out_of_range&) _NOEXCEPT = default; virtual ~out_of_range() _NOEXCEPT; #endif @@ -177,7 +177,7 @@ _LIBCPP_INLINE_VISIBILITY explicit range_error(const string& __s) : runtime_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit range_error(const char* __s) : runtime_error(__s) {} -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION range_error(const range_error&) _NOEXCEPT = default; virtual ~range_error() _NOEXCEPT; #endif @@ -190,7 +190,7 @@ _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const string& __s) : runtime_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit overflow_error(const char* __s) : runtime_error(__s) {} -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION overflow_error(const overflow_error&) _NOEXCEPT = default; virtual ~overflow_error() _NOEXCEPT; #endif @@ -203,7 +203,7 @@ _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const string& __s) : runtime_error(__s) {} _LIBCPP_INLINE_VISIBILITY explicit underflow_error(const char* __s) : runtime_error(__s) {} -#ifndef _LIBCPP_ABI_VCRUNTIME +#ifndef _LIBCPP_ABI_VCRUNTIME_EXCEPTION underflow_error(const underflow_error&) _NOEXCEPT = default; virtual ~underflow_error() _NOEXCEPT; #endif diff --git a/libcxx/include/typeinfo b/libcxx/include/typeinfo --- a/libcxx/include/typeinfo +++ b/libcxx/include/typeinfo @@ -342,6 +342,15 @@ }; #endif // defined(_LIBCPP_ABI_MICROSOFT) +} // std + +#endif // defined(_LIBCPP_ABI_VCRUNTIME) + +#if !defined(_LIBCPP_ABI_VCRUNTIME_EXCEPTION) + +namespace std // purposefully not using versioning namespace +{ + class _LIBCPP_EXCEPTION_ABI bad_cast : public exception { @@ -363,7 +372,7 @@ } // std -#endif // defined(_LIBCPP_ABI_VCRUNTIME) +#endif // defined(_LIBCPP_ABI_VCRUNTIME_EXCEPTION) _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_NORETURN inline _LIBCPP_INLINE_VISIBILITY diff --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h --- a/libcxx/test/support/test_macros.h +++ b/libcxx/test/support/test_macros.h @@ -252,8 +252,9 @@ # define RTTI_ASSERT(X) #endif -#if !TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cpp_exceptions) \ - && !defined(__EXCEPTIONS) +#if (!TEST_HAS_FEATURE(cxx_exceptions) && !defined(__cpp_exceptions) \ + && !defined(__EXCEPTIONS)) \ + || (defined(_HAS_EXCEPTIONS) && _HAS_EXCEPTIONS == 0) #define TEST_HAS_NO_EXCEPTIONS #endif diff --git a/libcxx/utils/ci/buildkite-pipeline.yml b/libcxx/utils/ci/buildkite-pipeline.yml --- a/libcxx/utils/ci/buildkite-pipeline.yml +++ b/libcxx/utils/ci/buildkite-pipeline.yml @@ -374,6 +374,17 @@ - exit_status: -1 # Agent was lost limit: 2 + - label: "Windows (_HAS_EXCEPTIONS=0)" + command: "bash libcxx/utils/ci/run-buildbot windows-noexceptions" + artifact_paths: + - "**/test-results.xml" + agents: + queue: "windows" + retry: + automatic: + - exit_status: -1 # Agent was lost + limit: 2 + - label: "32 bit" command: "libcxx/utils/ci/run-buildbot generic-32bit" artifact_paths: diff --git a/libcxx/utils/ci/run-buildbot b/libcxx/utils/ci/run-buildbot --- a/libcxx/utils/ci/run-buildbot +++ b/libcxx/utils/ci/run-buildbot @@ -108,8 +108,8 @@ -DCMAKE_C_COMPILER=clang-cl \ -DCMAKE_CXX_COMPILER=clang-cl \ -DLIBCXX_ENABLE_FILESYSTEM=YES \ - -DCMAKE_CXX_FLAGS="-D_LIBCPP_HAS_NO_INT128" \ - -DLIBCXX_TEST_COMPILER_FLAGS="-D_LIBCPP_HAS_NO_INT128" \ + -DCMAKE_CXX_FLAGS="-D_LIBCPP_HAS_NO_INT128 $EXTRA_CFLAGS" \ + -DLIBCXX_TEST_COMPILER_FLAGS="-D_LIBCPP_HAS_NO_INT128 $EXTRA_TESTFLAGS" \ "${@}" } @@ -553,6 +553,16 @@ echo "+++ Running the libc++ tests" ${NINJA} -vC "${BUILD_DIR}" check-cxx ;; +windows-noexceptions) + clean + # Building libc++ in the same way as in windows-dll above, but running + # tests with -D_HAS_EXCEPTIONS=0, which users might set in certain + # translation units while using libc++, even if libc++ is built with + # exceptions enabled. + EXTRA_TESTFLAGS="-D_HAS_EXCEPTIONS=0" generate-cmake-libcxx-win -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF + echo "+++ Running the libc++ tests" + ${NINJA} -vC "${BUILD_DIR}" check-cxx +;; ################################################################# # Insert vendor-specific internal configurations below. # diff --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py --- a/libcxx/utils/libcxx/test/features.py +++ b/libcxx/utils/libcxx/test/features.py @@ -31,6 +31,13 @@ when=lambda cfg: hasCompileFlag(cfg, '-Wuser-defined-warnings'), actions=[AddCompileFlag('-Wuser-defined-warnings')]), + # Normally, the feature 'no-exceptions' is set in params.py if + # running tests with enable_exceptions=false, but if we didn't set + # that and only defined _HAS_EXCEPTIONS=0, pick up on that and set the + # no-exceptions feature so certain tests are omitted. + # It would probably be fine to just run that test configuration with + # enable_exceptions=false too. + Feature(name='no-exceptions', when=lambda cfg: '_HAS_EXCEPTIONS' in compilerMacros(cfg) and compilerMacros(cfg)['_HAS_EXCEPTIONS'] == '0'), Feature(name='has-fblocks', when=lambda cfg: hasCompileFlag(cfg, '-fblocks')), Feature(name='-fsized-deallocation', when=lambda cfg: hasCompileFlag(cfg, '-fsized-deallocation')), Feature(name='-faligned-allocation', when=lambda cfg: hasCompileFlag(cfg, '-faligned-allocation')), diff --git a/libcxx/utils/libcxx/test/params.py b/libcxx/utils/libcxx/test/params.py --- a/libcxx/utils/libcxx/test/params.py +++ b/libcxx/utils/libcxx/test/params.py @@ -36,6 +36,12 @@ '-Wunused-parameter', '-Wunreachable-code', '-Wno-unused-local-typedef', + + # PR50676, affects MSVC mode without exceptions. This is only a temporary + # hack - ideally we'd at most add this flag in that particular configuration, + # not in all configurations, but flags passed via LIBCXX_TEST_COMPILER_FLAGS + # are set before these flags, so e.g. -Wall added here reenables it. + '-Wno-misleading-indentation', ] _allStandards = ['c++03', 'c++11', 'c++14', 'c++17', 'c++20', 'c++2b']