forked from OSchip/llvm-project
[libc++] Disentangle std::pointer_safety
This patch gets rid of technical debt around std::pointer_safety which, I claim, is entirely unnecessary. I don't think anybody has used std::pointer_safety in actual code because we do not implement the underlying garbage collection support. In fact, P2186 even proposes removing these facilities entirely from a future C++ version. As such, I think it's entirely fine to get rid of complex workarounds whose goals were to avoid breaking the ABI back in 2017. I'm putting this up both to get reviews and to discuss this proposal for a breaking change. I think we should be comfortable with making these tiny breaks if we are confident they won't hurt anyone, which I'm fairly confident is the case here. Differential Revision: https://reviews.llvm.org/D100410
This commit is contained in:
parent
1d299252dd
commit
49e7be2e5b
|
@ -55,3 +55,13 @@ API Changes
|
|||
|
||||
Also, the extension allowing a tuple to be constructed from an array has been
|
||||
removed. See https://godbolt.org/z/5esqbW.
|
||||
|
||||
- The ``std::pointer_safety`` utility and related functions are not available
|
||||
in C++03 anymore. Furthermore, in other standard modes, it has changed from
|
||||
a struct to a scoped enumeration, which is an ABI break. Finally, the
|
||||
``std::get_pointer_safety`` function was previously in the dylib, but it
|
||||
is now defined as inline in the headers.
|
||||
|
||||
While this is technically both an API and an ABI break, we do not expect
|
||||
``std::pointer_safety`` to have been used at all in real code, since we
|
||||
never implemented the underlying support for garbage collection.
|
||||
|
|
|
@ -88,11 +88,6 @@
|
|||
// provided under the alternate keyword __nullptr, which changes the mangling
|
||||
// of nullptr_t. This option is ABI incompatible with GCC in C++03 mode.
|
||||
# define _LIBCPP_ABI_ALWAYS_USE_CXX11_NULLPTR
|
||||
// Define the `pointer_safety` enum as a C++11 strongly typed enumeration
|
||||
// instead of as a class simulating an enum. If this option is enabled
|
||||
// `pointer_safety` and `get_pointer_safety()` will no longer be available
|
||||
// in C++03.
|
||||
# define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE
|
||||
// Define a key function for `bad_function_call` in the library, to centralize
|
||||
// its vtable and typeinfo to libc++ rather than having all other libraries
|
||||
// using that class define their own copies.
|
||||
|
|
|
@ -21,50 +21,18 @@ _LIBCPP_PUSH_MACROS
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
//enum class
|
||||
#if defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
|
||||
# ifndef _LIBCPP_CXX03_LANG
|
||||
#if !defined(_LIBCPP_CXX03_LANG)
|
||||
|
||||
enum class pointer_safety : unsigned char {
|
||||
relaxed,
|
||||
preferred,
|
||||
strict
|
||||
};
|
||||
# endif
|
||||
#else
|
||||
struct _LIBCPP_TYPE_VIS pointer_safety
|
||||
{
|
||||
enum __lx
|
||||
{
|
||||
relaxed,
|
||||
preferred,
|
||||
strict
|
||||
};
|
||||
|
||||
__lx __v_;
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer_safety() : __v_() {}
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pointer_safety(__lx __v) : __v_(__v) {}
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
operator int() const {return __v_;}
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \
|
||||
defined(_LIBCPP_BUILDING_LIBRARY)
|
||||
_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT;
|
||||
#else
|
||||
// This function is only offered in C++03 under ABI v1.
|
||||
# if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) || !defined(_LIBCPP_CXX03_LANG)
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
pointer_safety get_pointer_safety() _NOEXCEPT {
|
||||
return pointer_safety::relaxed;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
_LIBCPP_FUNC_VIS void declare_reachable(void* __p);
|
||||
_LIBCPP_FUNC_VIS void declare_no_pointers(char* __p, size_t __n);
|
||||
|
@ -79,6 +47,8 @@ undeclare_reachable(_Tp* __p)
|
|||
return static_cast<_Tp*>(__undeclare_reachable(__p));
|
||||
}
|
||||
|
||||
#endif // !C++03
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
_LIBCPP_POP_MACROS
|
||||
|
|
|
@ -651,12 +651,12 @@ template <class T, class Alloc>
|
|||
inline constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
|
||||
|
||||
// Pointer safety
|
||||
enum class pointer_safety { relaxed, preferred, strict };
|
||||
void declare_reachable(void *p);
|
||||
template <class T> T *undeclare_reachable(T *p);
|
||||
void declare_no_pointers(char *p, size_t n);
|
||||
void undeclare_no_pointers(char *p, size_t n);
|
||||
pointer_safety get_pointer_safety() noexcept;
|
||||
enum class pointer_safety { relaxed, preferred, strict }; // since C++11
|
||||
void declare_reachable(void *p); // since C++11
|
||||
template <class T> T *undeclare_reachable(T *p); // since C++11
|
||||
void declare_no_pointers(char *p, size_t n); // since C++11
|
||||
void undeclare_no_pointers(char *p, size_t n); // since C++11
|
||||
pointer_safety get_pointer_safety() noexcept; // since C++11
|
||||
|
||||
void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
|
||||
|
||||
|
|
|
@ -1507,7 +1507,6 @@
|
|||
{'is_defined': True, 'name': '__ZNSt3__118condition_variable4waitERNS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__118condition_variableD1Ev', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__118condition_variableD2Ev', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__118get_pointer_safetyEv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutex11lock_sharedEv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutex13unlock_sharedEv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '__ZNSt3__118shared_timed_mutex15try_lock_sharedEv', 'type': 'FUNC'}
|
||||
|
|
|
@ -1194,7 +1194,6 @@
|
|||
{'is_defined': True, 'name': '_ZNSt3__118condition_variable4waitERNS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__118condition_variableD1Ev', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__118condition_variableD2Ev', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__118get_pointer_safetyEv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex11lock_sharedEv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex13unlock_sharedEv', 'type': 'FUNC'}
|
||||
{'is_defined': True, 'name': '_ZNSt3__118shared_timed_mutex15try_lock_sharedEv', 'type': 'FUNC'}
|
||||
|
|
|
@ -198,13 +198,6 @@ undeclare_no_pointers(char*, size_t)
|
|||
{
|
||||
}
|
||||
|
||||
#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
|
||||
pointer_safety get_pointer_safety() noexcept
|
||||
{
|
||||
return pointer_safety::relaxed;
|
||||
}
|
||||
#endif
|
||||
|
||||
void*
|
||||
__undeclare_reachable(void* p)
|
||||
{
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <memory>
|
||||
|
||||
// pointer_safety get_pointer_safety();
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
// libc++ doesn't offer std::pointer_safety in C++03 under the new ABI
|
||||
#if TEST_STD_VER < 11 && defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE)
|
||||
#define TEST_IS_UNSUPPORTED
|
||||
#endif
|
||||
|
||||
#ifndef TEST_IS_UNSUPPORTED
|
||||
void test_pr26961() {
|
||||
std::pointer_safety d;
|
||||
d = std::get_pointer_safety();
|
||||
assert(d == std::get_pointer_safety());
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
#ifndef TEST_IS_UNSUPPORTED
|
||||
{
|
||||
// Test that std::pointer_safety is still offered in C++03 under the old ABI.
|
||||
std::pointer_safety r = std::get_pointer_safety();
|
||||
assert(r == std::pointer_safety::relaxed ||
|
||||
r == std::pointer_safety::preferred ||
|
||||
r == std::pointer_safety::strict);
|
||||
}
|
||||
{
|
||||
test_pr26961();
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// <memory>
|
||||
|
||||
// pointer_safety get_pointer_safety();
|
||||
|
||||
// The pointer_safety interface is no longer provided in C++03 in the new ABI.
|
||||
// XFAIL: c++03
|
||||
|
||||
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
static_assert(std::is_enum<std::pointer_safety>::value, "");
|
||||
static_assert(!std::is_convertible<std::pointer_safety, int>::value, "");
|
||||
static_assert(std::is_same<
|
||||
std::underlying_type<std::pointer_safety>::type,
|
||||
unsigned char
|
||||
>::value, "");
|
||||
}
|
||||
{
|
||||
std::pointer_safety r = std::get_pointer_safety();
|
||||
assert(r == std::pointer_safety::relaxed ||
|
||||
r == std::pointer_safety::preferred ||
|
||||
r == std::pointer_safety::strict);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -6,6 +6,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
|
||||
// <memory>
|
||||
|
||||
// void declare_no_pointers(char* p, size_t n);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++03
|
||||
|
||||
// <memory>
|
||||
|
||||
// void declare_reachable(void* p);
|
||||
|
|
|
@ -17,23 +17,27 @@
|
|||
|
||||
#include "test_macros.h"
|
||||
|
||||
|
||||
void test_pr26961() {
|
||||
std::pointer_safety d;
|
||||
d = std::get_pointer_safety();
|
||||
assert(d == std::get_pointer_safety());
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
static_assert(std::is_enum<std::pointer_safety>::value, "");
|
||||
static_assert(!std::is_convertible<std::pointer_safety, int>::value, "");
|
||||
static_assert(std::is_same<
|
||||
std::underlying_type<std::pointer_safety>::type,
|
||||
unsigned char
|
||||
>::value, "");
|
||||
}
|
||||
{
|
||||
std::pointer_safety r = std::get_pointer_safety();
|
||||
assert(r == std::pointer_safety::relaxed ||
|
||||
r == std::pointer_safety::preferred ||
|
||||
r == std::pointer_safety::strict);
|
||||
}
|
||||
// Regression test for https://llvm.org/PR26961
|
||||
{
|
||||
test_pr26961();
|
||||
std::pointer_safety d;
|
||||
d = std::get_pointer_safety();
|
||||
assert(d == std::get_pointer_safety());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue