Implement p0137r1 - std::launder. Reviewed as https://reviews.llvm.org/D40144
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@318864 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -456,6 +456,10 @@ namespace std {
|
|||||||
#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
|
#define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_builtin(__builtin_launder)
|
||||||
|
#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif defined(_LIBCPP_COMPILER_GCC)
|
#elif defined(_LIBCPP_COMPILER_GCC)
|
||||||
|
|
||||||
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
|
#define _ALIGNAS(x) __attribute__((__aligned__(x)))
|
||||||
@@ -538,6 +542,10 @@ namespace std {
|
|||||||
#define _LIBCPP_HAS_NO_ASAN
|
#define _LIBCPP_HAS_NO_ASAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if _GNUC_VER >= 700
|
||||||
|
#define _LIBCPP_COMPILER_HAS_BUILTIN_LAUNDER
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif defined(_LIBCPP_COMPILER_MSVC)
|
#elif defined(_LIBCPP_COMPILER_MSVC)
|
||||||
|
|
||||||
#define _LIBCPP_TOSTRING2(x) #x
|
#define _LIBCPP_TOSTRING2(x) #x
|
||||||
|
|||||||
25
include/new
25
include/new
@@ -46,6 +46,8 @@ typedef void (*new_handler)();
|
|||||||
new_handler set_new_handler(new_handler new_p) noexcept;
|
new_handler set_new_handler(new_handler new_p) noexcept;
|
||||||
new_handler get_new_handler() 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
|
} // std
|
||||||
|
|
||||||
void* operator new(std::size_t size); // replaceable
|
void* operator new(std::size_t size); // replaceable
|
||||||
@@ -250,6 +252,29 @@ void __throw_bad_array_length()
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
_LIBCPP_END_NAMESPACE_STD
|
||||||
|
|
||||||
#endif // _LIBCPP_NEW
|
#endif // _LIBCPP_NEW
|
||||||
|
|||||||
@@ -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}}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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"}}
|
||||||
|
}
|
||||||
@@ -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/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/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/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/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/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>
|
<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>
|
||||||
|
|||||||
Reference in New Issue
Block a user