[libcxx-commits] [libcxx] 49e7be2 - [libc++] Disentangle std::pointer_safety

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon May 3 11:33:56 PDT 2021


Author: Louis Dionne
Date: 2021-05-03T14:33:49-04:00
New Revision: 49e7be2e5ba1759ae9d4ce9843ce2467cf7823a5

URL: https://github.com/llvm/llvm-project/commit/49e7be2e5ba1759ae9d4ce9843ce2467cf7823a5
DIFF: https://github.com/llvm/llvm-project/commit/49e7be2e5ba1759ae9d4ce9843ce2467cf7823a5.diff

LOG: [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

Added: 
    

Modified: 
    libcxx/docs/ReleaseNotes.rst
    libcxx/include/__config
    libcxx/include/__memory/pointer_safety.h
    libcxx/include/memory
    libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
    libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
    libcxx/src/memory.cpp
    libcxx/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp
    libcxx/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp
    libcxx/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp

Removed: 
    libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp
    libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp


################################################################################
diff  --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst
index 1bcb26de840d9..0cc8c00608efa 100644
--- a/libcxx/docs/ReleaseNotes.rst
+++ b/libcxx/docs/ReleaseNotes.rst
@@ -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.

diff  --git a/libcxx/include/__config b/libcxx/include/__config
index 431893fd9e2d1..49255a850f796 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -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.

diff  --git a/libcxx/include/__memory/pointer_safety.h b/libcxx/include/__memory/pointer_safety.h
index a32ffc4d0eaf9..bdfed3fa3a307 100644
--- a/libcxx/include/__memory/pointer_safety.h
+++ b/libcxx/include/__memory/pointer_safety.h
@@ -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

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index 74a430def2a3a..586bd14d2dab4 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -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);
 

diff  --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
index c472a3ae3ca2c..17739ea6ded82 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
@@ -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'}

diff  --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
index 46e3ef79240bc..927b36f594511 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.no_new_in_libcxx.abilist
@@ -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'}

diff  --git a/libcxx/src/memory.cpp b/libcxx/src/memory.cpp
index cb10b696cc4e7..9bd27df26834a 100644
--- a/libcxx/src/memory.cpp
+++ b/libcxx/src/memory.cpp
@@ -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)
 {

diff  --git a/libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp b/libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp
deleted file mode 100644
index deab4368af29f..0000000000000
--- a/libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_cxx03.pass.cpp
+++ /dev/null
@@ -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;
-}

diff  --git a/libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp b/libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp
deleted file mode 100644
index 44d336f342c43..0000000000000
--- a/libcxx/test/libcxx/utilities/memory/util.dynamic.safety/get_pointer_safety_new_abi.pass.cpp
+++ /dev/null
@@ -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;
-}

diff  --git a/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp b/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp
index 892479fbeafef..562f0058d6723 100644
--- a/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++03
+
 // <memory>
 
 // void declare_no_pointers(char* p, size_t n);

diff  --git a/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp b/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp
index 2d880ef5c0684..08d06d5822121 100644
--- a/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp
@@ -6,6 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+// UNSUPPORTED: c++03
+
 // <memory>
 
 // void declare_reachable(void* p);

diff  --git a/libcxx/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp b/libcxx/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
index b12ff901a7605..e6125721761b4 100644
--- a/libcxx/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
@@ -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;


        


More information about the libcxx-commits mailing list