diff --git a/include/boost/system/error_code.hpp b/include/boost/system/error_code.hpp index 57e7175..ad9f454 100644 --- a/include/boost/system/error_code.hpp +++ b/include/boost/system/error_code.hpp @@ -732,10 +732,14 @@ inline const error_category & generic_category() BOOST_SYSTEM_NOEXCEPT inline system::error_code* throws() { // See github.com/boostorg/system/pull/12 by visigoth for why the return - // is poisoned with (1) rather than (0). A test, test_throws_usage(), has - // been added to error_code_test.cpp, and as visigoth mentioned it fails - // on clang for release builds with a return of 0 but works fine with (1). - return reinterpret_cast(1); + // is poisoned with nonzero rather than (0). A test, test_throws_usage(), + // has been added to error_code_test.cpp, and as visigoth mentioned it + // fails on clang for release builds with a return of 0 but works fine + // with (1). + // Since the undefined behavior sanitizer (-fsanitize=undefined) does not + // allow a reference to be formed to the unaligned address of (1), we use + // (8) instead. + return reinterpret_cast(8); } } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 55e41c0..784fd8e 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -125,6 +125,7 @@ else [ run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : static : single_instance_lib_static ] [ run single_instance_test.cpp single_instance_lib1 single_instance_lib2 : : : shared : single_instance_lib_shared ] [ system-run before_main_test.cpp ] + [ run-fail throws_assign_fail.cpp ] [ system-run- constexpr_test.cpp ] ; diff --git a/test/error_code_test.cpp b/test/error_code_test.cpp index 1f96c59..7965541 100644 --- a/test/error_code_test.cpp +++ b/test/error_code_test.cpp @@ -22,7 +22,6 @@ #include #include #include -#include // Although using directives are not the best programming practice, testing // with a boost::system using directive increases use scenario coverage. @@ -247,17 +246,8 @@ int main( int, char ** ) BOOST_TEST( econd.message() != "" ); BOOST_TEST( econd.message().substr( 0, 13) != "Unknown error" ); -#if !defined(UBSAN) - - // the current implementation of boost::throws() relies on undefined behavior test_throws_usage(); -#else - - BOOST_PRAGMA_MESSAGE("Skipping test_throws_usage() due to UBSAN"); - -#endif - #ifdef BOOST_WINDOWS_API std::cout << "Windows tests...\n"; // these tests probe the Windows errc decoder diff --git a/test/throws_assign_fail.cpp b/test/throws_assign_fail.cpp new file mode 100644 index 0000000..8453577 --- /dev/null +++ b/test/throws_assign_fail.cpp @@ -0,0 +1,28 @@ + +// Copyright 2018 Peter Dimov. +// Distributed under the Boost Software License, Version 1.0. + +#include + +using namespace boost::system; + +static void f( error_code & ec ) +{ + ec = error_code(); +} + +#if defined(_WIN32) +# include // SetErrorMode +#endif + +int main() +{ +#if defined(_WIN32) + + SetErrorMode( SetErrorMode( 0 ) | SEM_NOGPFAULTERRORBOX ); + +#endif + + // this should crash + f( boost::throws() ); +}