Author: ericwf Date: Wed Jan 4 19:15:42 2017 New Revision: 291046 URL: http://llvm.org/viewvc/llvm-project?rev=291046&view=rev Log: Fix std::pointer_safety type in ABI v2
In the C++ standard `std::pointer_safety` is defined as a C++11 strongly typed enum. However libc++ currently defines it as a class type which simulates a C++11 enumeration. This can be detected in valid C++ code. This patch introduces an the _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE ABI option. When defined `std::pointer_safety` is implemented as an enum type. Unfortunatly this also means it can no longer be provided as an extension in C++03. Additionally this patch moves the definition for `get_pointer_safety()` out of the dylib, and into the headers. New usages of `get_pointer_safety()` will now use the inline version instead of the dylib version. However in order to keep the dylib ABI compatible the old definition is explicitly compiled into it. Added: libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/ libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp - copied, changed from r291039, libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp - copied, changed from r291039, libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp Modified: libcxx/trunk/include/__config libcxx/trunk/include/memory libcxx/trunk/src/memory.cpp libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp Modified: libcxx/trunk/include/__config URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=291046&r1=291045&r2=291046&view=diff ============================================================================== --- libcxx/trunk/include/__config (original) +++ libcxx/trunk/include/__config Wed Jan 4 19:15:42 2017 @@ -52,6 +52,11 @@ // 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 #elif _LIBCPP_ABI_VERSION == 1 #if !defined(_WIN32) // Enable compiling a definition of error_category() into the libc++ dylib. Modified: libcxx/trunk/include/memory URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=291046&r1=291045&r2=291046&view=diff ============================================================================== --- libcxx/trunk/include/memory (original) +++ libcxx/trunk/include/memory Wed Jan 4 19:15:42 2017 @@ -5616,6 +5616,15 @@ atomic_compare_exchange_weak_explicit(sh #endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER) //enum class +#if defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) +# ifndef _LIBCPP_CXX03_LANG +enum class pointer_safety : unsigned char { + relaxed, + preferred, + strict +}; +# endif +#else struct _LIBCPP_TYPE_VIS pointer_safety { enum __lx @@ -5632,11 +5641,25 @@ struct _LIBCPP_TYPE_VIS pointer_safety _LIBCPP_INLINE_VISIBILITY operator int() const {return __v_;} }; +#endif + +#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) && \ + defined(_LIBCPP_BUILDING_MEMORY) +_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); _LIBCPP_FUNC_VIS void undeclare_no_pointers(char* __p, size_t __n); -_LIBCPP_FUNC_VIS pointer_safety get_pointer_safety() _NOEXCEPT; _LIBCPP_FUNC_VIS void* __undeclare_reachable(void* __p); template <class _Tp> Modified: libcxx/trunk/src/memory.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/memory.cpp?rev=291046&r1=291045&r2=291046&view=diff ============================================================================== --- libcxx/trunk/src/memory.cpp (original) +++ libcxx/trunk/src/memory.cpp Wed Jan 4 19:15:42 2017 @@ -220,11 +220,12 @@ undeclare_no_pointers(char*, size_t) { } -pointer_safety -get_pointer_safety() _NOEXCEPT +#if !defined(_LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE) +pointer_safety get_pointer_safety() _NOEXCEPT { return pointer_safety::relaxed; } +#endif void* __undeclare_reachable(void* p) Copied: libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp (from r291039, libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp) URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp?p2=libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp&p1=libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp&r1=291039&r2=291046&rev=291046&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp (original) +++ libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp Wed Jan 4 19:15:42 2017 @@ -16,8 +16,11 @@ int main() { + // Test that std::pointer_safety is still offered in C++03 under the old ABI. +#ifndef _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE std::pointer_safety r = std::get_pointer_safety(); assert(r == std::pointer_safety::relaxed || r == std::pointer_safety::preferred || r == std::pointer_safety::strict); +#endif } Copied: libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp (from r291039, libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp) URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp?p2=libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp&p1=libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp&r1=291039&r2=291046&rev=291046&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp (original) +++ libcxx/trunk/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp Wed Jan 4 19:15:42 2017 @@ -11,13 +11,28 @@ // pointer_safety get_pointer_safety(); +// The pointer_safety interface is no longer provided in C++03 in the new ABI. +// XFAIL: c++98, c++03 + +// MODULES_DEFINES: _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE +#define _LIBCPP_ABI_POINTER_SAFETY_ENUM_TYPE #include <memory> #include <cassert> int main() { + { + 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); + } } Modified: libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp?rev=291046&r1=291045&r2=291046&view=diff ============================================================================== --- libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp (original) +++ libcxx/trunk/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp Wed Jan 4 19:15:42 2017 @@ -11,6 +11,8 @@ // pointer_safety get_pointer_safety(); +// UNSUPPORTED: c++98, c++03 + #include <memory> #include <cassert> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits