diff options
author | jacobly0 <jacobly0@users.noreply.github.com> | 2022-05-08 16:12:28 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-08 16:12:28 +0200 |
commit | e97a52820f34c4be8e628eea76885b1ded71518b (patch) | |
tree | 4507f6e5e6dd7666d27c04ce24b8dab84b0d8907 | |
parent | d96ddd06d4eb379efeef1aebd71ad4d26030eacd (diff) | |
download | ccache-e97a52820f34c4be8e628eea76885b1ded71518b.tar.gz |
fix: Fix miscompile of nonstd::expected on MSVC v19.22 (#1053)
-rw-r--r-- | src/third_party/nonstd/expected.hpp | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/src/third_party/nonstd/expected.hpp b/src/third_party/nonstd/expected.hpp index 69bee750..2bd18344 100644 --- a/src/third_party/nonstd/expected.hpp +++ b/src/third_party/nonstd/expected.hpp @@ -1,6 +1,6 @@ // This version targets C++11 and later. // -// Copyright (C) 2016-2018 Martin Moene. +// Copyright (C) 2016-2020 Martin Moene. // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -66,16 +66,25 @@ # define nsel_P0323R 7 #endif -// Control presence of exception handling (try and auto discover): +// Control presence of C++ exception handling (try and auto discover): #ifndef nsel_CONFIG_NO_EXCEPTIONS -# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND) +# if defined(_MSC_VER) +# include <cstddef> // for _HAS_EXCEPTIONS +# endif +# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) # define nsel_CONFIG_NO_EXCEPTIONS 0 # else # define nsel_CONFIG_NO_EXCEPTIONS 1 # endif #endif +// at default use SEH with MSVC for no C++ exceptions + +#ifndef nsel_CONFIG_NO_EXCEPTIONS_SEH +# define nsel_CONFIG_NO_EXCEPTIONS_SEH ( nsel_CONFIG_NO_EXCEPTIONS && _MSC_VER ) +#endif + // C++ language version detection (C++20 is speculative): // Note: VC14.0/1900 (VS2015) lacks too much from C++14. @@ -224,7 +233,11 @@ namespace nonstd { // additional includes: #if nsel_CONFIG_NO_EXCEPTIONS +# if nsel_CONFIG_NO_EXCEPTIONS_SEH +# include <windows.h> // for ExceptionCodes +# else // already included: <cassert> +# endif #else # include <stdexcept> #endif @@ -1260,7 +1273,11 @@ struct error_traits { static void rethrow( Error const & /*e*/ ) { +#if nsel_CONFIG_NO_EXCEPTIONS_SEH + RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL ); +#else assert( false && detail::text("throw bad_expected_access<Error>{ e };") ); +#endif } }; @@ -1269,7 +1286,11 @@ struct error_traits< std::exception_ptr > { static void rethrow( std::exception_ptr const & /*e*/ ) { +#if nsel_CONFIG_NO_EXCEPTIONS_SEH + RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL ); +#else assert( false && detail::text("throw bad_expected_access<std::exception_ptr>{ e };") ); +#endif } }; @@ -1278,7 +1299,11 @@ struct error_traits< std::error_code > { static void rethrow( std::error_code const & /*e*/ ) { +#if nsel_CONFIG_NO_EXCEPTIONS_SEH + RaiseException( EXCEPTION_ACCESS_VIOLATION, EXCEPTION_NONCONTINUABLE, 0, NULL ); +#else assert( false && detail::text("throw std::system_error( e );") ); +#endif } }; @@ -1639,10 +1664,11 @@ public: return *this; } - template< typename G + template< typename G = E nsel_REQUIRES_T( - std::is_copy_constructible<E>::value // TODO: std::is_nothrow_copy_constructible<E> - && std::is_copy_assignable<E>::value + std::is_constructible<E, G const&>::value && + std::is_copy_constructible<G>::value // TODO: std::is_nothrow_copy_constructible<G> + && std::is_copy_assignable<G>::value ) > expected & operator=( nonstd::unexpected_type<G> const & error ) @@ -1651,10 +1677,11 @@ public: return *this; } - template< typename G + template< typename G = E nsel_REQUIRES_T( - std::is_move_constructible<E>::value // TODO: std::is_nothrow_move_constructible<E> - && std::is_move_assignable<E>::value + std::is_constructible<E, G&&>::value && + std::is_move_constructible<G>::value // TODO: std::is_nothrow_move_constructible<G> + && std::is_move_assignable<G>::value ) > expected & operator=( nonstd::unexpected_type<G> && error ) @@ -1742,12 +1769,12 @@ public: constexpr value_type const && operator *() const && { - return assert( has_value() ), std::move( contained.value() ); + return std::move( ( assert( has_value() ), contained.value() ) ); } nsel_constexpr14 value_type && operator *() && { - return assert( has_value() ), std::move( contained.value() ); + return std::move( ( assert( has_value() ), contained.value() ) ); } #endif @@ -1808,12 +1835,12 @@ public: constexpr error_type const && error() const && { - return assert( ! has_value() ), std::move( contained.error() ); + return std::move( ( assert( ! has_value() ), contained.error() ) ); } error_type && error() && { - return assert( ! has_value() ), std::move( contained.error() ); + return std::move( ( assert( ! has_value() ), contained.error() ) ); } #endif @@ -2080,12 +2107,12 @@ public: constexpr error_type const && error() const && { - return assert( ! has_value() ), std::move( contained.error() ); + return std::move( ( assert( ! has_value() ), contained.error() ) ); } error_type && error() && { - return assert( ! has_value() ), std::move( contained.error() ); + return std::move( ( assert( ! has_value() ), contained.error() ) ); } #endif |