diff --git a/doc/html/boost_config/boost_macro_reference.html b/doc/html/boost_config/boost_macro_reference.html index 8948684bc..87c976eda 100644 --- a/doc/html/boost_config/boost_macro_reference.html +++ b/doc/html/boost_config/boost_macro_reference.html @@ -1576,6 +1576,26 @@

+ + +

+ BOOST_HAS_BUILTIN_LAUNDER +

+ + +

+ Compiler +

+ + +

+ The compiler implements the + __builtin_launder() + compiler intrinsic that is needed to implement a constexpr + pointer laundering function like std::launder. +

+ +

diff --git a/doc/macro_reference.qbk b/doc/macro_reference.qbk index 9a2d1565e..23d2dbc58 100644 --- a/doc/macro_reference.qbk +++ b/doc/macro_reference.qbk @@ -405,6 +405,10 @@ standard. The macro is only defined if the feature is present. [[`BOOST_HAS_BETHREADS`][Platform][ The platform supports BeOS style threads. ]] +[[`BOOST_HAS_BUILTIN_LAUNDER`][Compiler][ +The compiler implements the `__builtin_launder()` compiler intrinsic that is needed +to implement a constexpr pointer laundering function like `std::launder`. +]] [[`BOOST_HAS_CLOCK_GETTIME`][Platform][ The platform has the POSIX API `clock_gettime`. ]] diff --git a/include/boost/config/compiler/gcc.hpp b/include/boost/config/compiler/gcc.hpp index 2f1fe5508..278d12849 100644 --- a/include/boost/config/compiler/gcc.hpp +++ b/include/boost/config/compiler/gcc.hpp @@ -353,6 +353,11 @@ #define BOOST_DEPRECATED(msg) __attribute__((deprecated)) #endif +// __builtin_launder intrinsic +#if BOOST_GCC_VERSION >= 70000 +# define BOOST_HAS_BUILTIN_LAUNDER +#endif + #ifndef BOOST_COMPILER # define BOOST_COMPILER "GNU C++ version " __VERSION__ #endif diff --git a/include/boost/config/compiler/visualc.hpp b/include/boost/config/compiler/visualc.hpp index ae631219a..3e288f130 100644 --- a/include/boost/config/compiler/visualc.hpp +++ b/include/boost/config/compiler/visualc.hpp @@ -115,6 +115,12 @@ #define BOOST_DEPRECATED(msg) __declspec(deprecated) #endif +// __builtin_launder intrinsic +//The intrinsic is only available in C++17 or later mode +#if (_MSC_VER >= 1910) && defined(_MSVC_LANG) && (_MSVC_LANG > 201402L) +# define BOOST_HAS_BUILTIN_LAUNDER +#endif + // // TR1 features: // diff --git a/include/boost/config/detail/suffix.hpp b/include/boost/config/detail/suffix.hpp index b28d46f18..5d3acac84 100644 --- a/include/boost/config/detail/suffix.hpp +++ b/include/boost/config/detail/suffix.hpp @@ -1276,6 +1276,13 @@ namespace std{ using ::type_info; } # define BOOST_NO_CXX17_DEDUCTION_GUIDES #endif +// Generic __builtin_launder intrinsic in case it's not detected by the compiler file +#if !defined(BOOST_HAS_BUILTIN_LAUNDER) && defined(__has_builtin) +# if __has_builtin(__builtin_launder) +# define BOOST_HAS_BUILTIN_LAUNDER +# endif +#endif + // // Define composite agregate macros: // diff --git a/test/all/Jamfile.v2 b/test/all/Jamfile.v2 index afa805036..44e8a499c 100644 --- a/test/all/Jamfile.v2 +++ b/test/all/Jamfile.v2 @@ -28,6 +28,9 @@ test-suite "BOOST_HAS_TWO_ARG_USE_FACET" : test-suite "BOOST_HAS_BETHREADS" : [ run ../has_bethreads_pass.cpp ] [ compile-fail ../has_bethreads_fail.cpp ] ; +test-suite "BOOST_HAS_BUILTIN_LAUNDER" : +[ run ../has_builtin_launder_pass.cpp ] +[ compile-fail ../has_builtin_launder_fail.cpp ] ; test-suite "BOOST_HAS_CLOCK_GETTIME" : [ run ../has_clock_gettime_pass.cpp ] [ compile-fail ../has_clock_gettime_fail.cpp ] ; diff --git a/test/boost_has_builtin_launder.ipp b/test/boost_has_builtin_launder.ipp new file mode 100644 index 000000000..353c32253 --- /dev/null +++ b/test/boost_has_builtin_launder.ipp @@ -0,0 +1,29 @@ +// (C) Copyright Ion Gaztanaga 2022. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org/libs/config for most recent version. + +// MACRO: BOOST_HAS_BUILTIN_LAUNDER +// TITLE: __builtin_launder +// DESCRIPTION: The platform supports __builtin_launder. + +#include + +namespace boost_has_builtin_launder { + +struct X +{ + const int const_int; +}; + +int test() +{ + X original{1}; + new (&original) X{2}; //Overwrite X + return __builtin_launder(&original)->const_int == 2 ? 0 : -1; //After laundering, new value should be returned +} + +} //namespace boost_has_builtin_launder { + diff --git a/test/has_builtin_launder_fail.cpp b/test/has_builtin_launder_fail.cpp new file mode 100644 index 000000000..26a35fc92 --- /dev/null +++ b/test/has_builtin_launder_fail.cpp @@ -0,0 +1,32 @@ +// This file was automatically generated on Fri Dec 03 18:03:59 2004 +// by libs/config/tools/generate.cpp +// Copyright Ion Gaztanaga 2022. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org/libs/config for the most recent version. + +// Test file for macro BOOST_HAS_BUILTIN_LAUNDER +// This file should not compile, if it does then +// BOOST_HAS_BUILTIN_LAUNDER should be defined. +// See file boost_has_builtin_launder.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include + +#ifndef BOOST_HAS_BUILTIN_LAUNDER +#include "boost_has_builtin_launder.ipp" +#else +#error "this file should not compile" +#endif + +int main( int, char *[] ) +{ + return boost_has_builtin_launder::test(); +} diff --git a/test/has_builtin_launder_pass.cpp b/test/has_builtin_launder_pass.cpp new file mode 100644 index 000000000..e23c53c9d --- /dev/null +++ b/test/has_builtin_launder_pass.cpp @@ -0,0 +1,34 @@ +// This file was automatically generated on Fri Dec 03 18:03:59 2004 +// by libs/config/tools/generate.cpp +// Copyright Ion Gaztanaga 2022. +// Use, modification and distribution are subject to 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) + +// See http://www.boost.org/libs/config for the most recent version. + +// Test file for macro BOOST_HAS_BUILTIN_LAUNDER +// This file should compile, if it does not then +// BOOST_HAS_BUILTIN_LAUNDER should not be defined. +// See file boost_has_builtin_launder.ipp for details + +// Must not have BOOST_ASSERT_CONFIG set; it defeats +// the objective of this file: +#ifdef BOOST_ASSERT_CONFIG +# undef BOOST_ASSERT_CONFIG +#endif + +#include +#include "test.hpp" + +#ifdef BOOST_HAS_BUILTIN_LAUNDER +#include "boost_has_builtin_launder.ipp" +#else +namespace boost_has_builtin_launder = empty_boost; +#endif + +int main( int, char *[] ) +{ + return boost_has_builtin_launder::test(); +} +