diff options
author | Marshall Clow <mclow.lists@gmail.com> | 2017-11-22 19:49:03 +0000 |
---|---|---|
committer | Marshall Clow <mclow.lists@gmail.com> | 2017-11-22 19:49:03 +0000 |
commit | 9180eb1f4ab96481413e93d35f35c3685de3084c (patch) | |
tree | cd567a3da8ebf76d616d8dbc2ea2111ae725409c | |
parent | 374cff69e0c54989e8e8a7426b74b0b248c4885d (diff) | |
download | bcm5719-llvm-9180eb1f4ab96481413e93d35f35c3685de3084c.tar.gz bcm5719-llvm-9180eb1f4ab96481413e93d35f35c3685de3084c.zip |
Implement p0137r1 - std::launder. Reviewed as https://reviews.llvm.org/D40144
llvm-svn: 318864
6 files changed, 130 insertions, 0 deletions
diff --git a/libcxx/include/__config b/libcxx/include/__config index 561eb36ac1d..70a34e1c074 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -456,6 +456,10 @@ namespace std { #define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow"))) #endif +#if __has_builtin(__builtin_launder) +#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER +#endif + #elif defined(_LIBCPP_COMPILER_GCC) #define _ALIGNAS(x) __attribute__((__aligned__(x))) @@ -538,6 +542,10 @@ namespace std { #define _LIBCPP_HAS_NO_ASAN #endif +#if _GNUC_VER >= 700 +#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER +#endif + #elif defined(_LIBCPP_COMPILER_MSVC) #define _LIBCPP_TOSTRING2(x) #x diff --git a/libcxx/include/new b/libcxx/include/new index 06cf4a3e160..6541e021865 100644 --- a/libcxx/include/new +++ b/libcxx/include/new @@ -46,6 +46,8 @@ typedef void (*new_handler)(); new_handler set_new_handler(new_handler new_p) noexcept; new_handler get_new_handler() noexcept; +// 21.6.4, pointer optimization barrier +template <class T> constexpr T* launder(T* p) noexcept; // C++17 } // std void* operator new(std::size_t size); // replaceable @@ -250,6 +252,29 @@ void __throw_bad_array_length() } #endif +template <class _Tp> +_LIBCPP_NODISCARD_AFTER_CXX17 inline +_LIBCPP_CONSTEXPR _Tp* __launder(_Tp* __p) _NOEXCEPT +{ + static_assert (!(is_function<_Tp>::value), "can't launder functions" ); + static_assert (!(is_same<void, typename remove_cv<_Tp>::type>::value), "can't launder cv-void" ); +#ifdef _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER + return __builtin_launder(__p); +#else + return __p; +#endif +} + + +#if _LIBCPP_STD_VER > 14 +template <class _Tp> +_LIBCPP_NODISCARD_AFTER_CXX17 inline _LIBCPP_INLINE_VISIBILITY +constexpr _Tp* launder(_Tp* __p) noexcept +{ + return __launder(__p); +} +#endif + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_NEW diff --git a/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.nodiscard.fail.cpp b/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.nodiscard.fail.cpp new file mode 100644 index 00000000000..1c75e561d7c --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.nodiscard.fail.cpp @@ -0,0 +1,27 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <new> + +// template <class T> constexpr T* launder(T* p) noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14, c++17 +// UNSUPPORTED: clang-3.3, clang-3.4, clang-3.5, clang-3.6, clang-3.7, clang-3.8 + +#include <new> +#include <cassert> + +#include "test_macros.h" + +int main () +{ + int *p = nullptr; + std::launder(p); // expected-error {{ignoring return value of function declared with 'nodiscard' attribute}} +} diff --git a/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.pass.cpp b/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.pass.cpp new file mode 100644 index 00000000000..1aa462957c8 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <new> + +// template <class T> constexpr T* launder(T* p) noexcept; + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +#include <new> +#include <cassert> + +#include "test_macros.h" + +constexpr int gi = 5; +constexpr float gf = 8.f; + +int main() { + static_assert(std::launder(&gi) == &gi, "" ); + static_assert(std::launder(&gf) == &gf, "" ); + + const int *i = &gi; + const float *f = &gf; + static_assert(std::is_same<decltype(i), decltype(std::launder(i))>::value, ""); + static_assert(std::is_same<decltype(f), decltype(std::launder(f))>::value, ""); + + assert(std::launder(i) == i); + assert(std::launder(f) == f); +} diff --git a/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp b/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp new file mode 100644 index 00000000000..71f5e4588b8 --- /dev/null +++ b/libcxx/test/std/language.support/support.dynamic/ptr.launder/launder.types.fail.cpp @@ -0,0 +1,34 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// <new> + +// template <class T> constexpr T* launder(T* p) noexcept; +// The program is ill-formed if T is a function type or cv void. + +// UNSUPPORTED: c++98, c++03, c++11, c++14 + +#include <new> +#include <cassert> + +#include "test_macros.h" + +void foo() {} + +int main () +{ + void *p = nullptr; + (void) std::launder(( void *) nullptr); + (void) std::launder((const void *) nullptr); + (void) std::launder(( volatile void *) nullptr); + (void) std::launder((const volatile void *) nullptr); // expected-error-re@new:* 4 {{static_assert failed{{.*}} "can't launder cv-void"}} + + (void) std::launder(foo); // expected-error-re@new:* 1 {{static_assert failed{{.*}} "can't launder functions"}} +} diff --git a/libcxx/www/cxx1z_status.html b/libcxx/www/cxx1z_status.html index ca4801b3a4e..66485699292 100644 --- a/libcxx/www/cxx1z_status.html +++ b/libcxx/www/cxx1z_status.html @@ -104,6 +104,7 @@ <tr><td><a href="https://wg21.link/p0083r3">p0083r3</a></td><td>LWG</td><td>Splicing Maps and Sets</td><td>Oulu</td><td></td><td></td></tr> <tr><td><a href="https://wg21.link/p0084r2">p0084r2</a></td><td>LWG</td><td>Emplace Return Type</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr> <tr><td><a href="https://wg21.link/p0088r3">p0088r3</a></td><td>LWG</td><td>Variant: a type-safe union for C++17</td><td>Oulu</td><td>Complete</td><td>4.0</td></tr> + <tr><td><a href="https://wg21.link/p0137r1">p0137r1</a></td><td>CWG</td><td>Core Issue 1776: Replacement of class objects containing reference members</td><td>Oulu</td><td>Complete</td><td>6.0</td></tr> <tr><td><a href="https://wg21.link/p0163r0">p0163r0</a></td><td>LWG</td><td>shared_ptr::weak_type</td><td>Oulu</td><td>Complete</td><td>3.9</td></tr> <tr><td><a href="https://wg21.link/p0174r2">p0174r2</a></td><td>LWG</td><td>Deprecating Vestigial Library Parts in C++17</td><td>Oulu</td><td></td><td></td></tr> <tr><td><a href="https://wg21.link/p0175r1">p0175r1</a></td><td>LWG</td><td>Synopses for the C library</td><td>Oulu</td><td></td><td></td></tr> |