[libc++] Implement P2186R2 (Remove Garbage Collection)

Reviewed By: Quuxplusone, #libc, ldionne

Differential Revision: https://reviews.llvm.org/D112869

GitOrigin-RevId: b57c22ade8673d68088f5638a1050e3f3c1f163d
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 5f81b3e..9ccb211 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -82,6 +82,11 @@
   ``std::chrono::file_clock::from_time_t``; neither libstdc++ nor MSVC STL
   had such methods.
 
+- The declarations of functions ``declare_reachable``, ``undeclare_reachable``, ``declare_no_pointers``,
+  ``undeclare_no_pointers``, and ``get_pointer_safety`` have been removed not only from C++2b but
+  from all modes. Their symbols are still provided by the dynamic library for the benefit of
+  existing compiled code. All of these functions have always behaved as no-ops.
+
 ABI Changes
 -----------
 
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index ed1a585..fe03e25 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -220,7 +220,6 @@
   __memory/auto_ptr.h
   __memory/compressed_pair.h
   __memory/construct_at.h
-  __memory/pointer_safety.h
   __memory/pointer_traits.h
   __memory/raw_storage_iterator.h
   __memory/shared_ptr.h
diff --git a/include/__memory/pointer_safety.h b/include/__memory/pointer_safety.h
deleted file mode 100644
index e720803..0000000
--- a/include/__memory/pointer_safety.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___MEMORY_POINTER_SAFETY_H
-#define _LIBCPP___MEMORY_POINTER_SAFETY_H
-
-#include <__config>
-#include <cstddef>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#pragma GCC system_header
-#endif
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if !defined(_LIBCPP_CXX03_LANG)
-
-enum class pointer_safety : unsigned char {
-  relaxed,
-  preferred,
-  strict
-};
-
-inline _LIBCPP_INLINE_VISIBILITY
-pointer_safety get_pointer_safety() _NOEXCEPT {
-  return pointer_safety::relaxed;
-}
-
-_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 void* __undeclare_reachable(void* __p);
-
-template <class _Tp>
-inline _LIBCPP_INLINE_VISIBILITY
-_Tp*
-undeclare_reachable(_Tp* __p)
-{
-    return static_cast<_Tp*>(__undeclare_reachable(__p));
-}
-
-#endif // !C++03
-
-_LIBCPP_END_NAMESPACE_STD
-
-#endif // _LIBCPP___MEMORY_POINTER_SAFETY_H
diff --git a/include/memory b/include/memory
index b1d16ef..c5eafe1 100644
--- a/include/memory
+++ b/include/memory
@@ -655,14 +655,6 @@
 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 }; // 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);
 
 }  // std
@@ -678,7 +670,6 @@
 #include <__memory/allocator_traits.h>
 #include <__memory/compressed_pair.h>
 #include <__memory/construct_at.h>
-#include <__memory/pointer_safety.h>
 #include <__memory/pointer_traits.h>
 #include <__memory/raw_storage_iterator.h>
 #include <__memory/shared_ptr.h>
diff --git a/include/module.modulemap b/include/module.modulemap
index 80cdfe3..2f96f9a 100644
--- a/include/module.modulemap
+++ b/include/module.modulemap
@@ -620,7 +620,6 @@
       module auto_ptr                 { private header "__memory/auto_ptr.h"                 }
       module compressed_pair          { private header "__memory/compressed_pair.h"          }
       module construct_at             { private header "__memory/construct_at.h"             }
-      module pointer_safety           { private header "__memory/pointer_safety.h"           }
       module pointer_traits           { private header "__memory/pointer_traits.h"           }
       module raw_storage_iterator     { private header "__memory/raw_storage_iterator.h"     }
       module shared_ptr               { private header "__memory/shared_ptr.h"               }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index dbd0135..d52c530 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -19,6 +19,7 @@
   include/atomic_support.h
   include/config_elast.h
   include/refstring.h
+  legacy_pointer_safety.cpp
   memory.cpp
   mutex.cpp
   mutex_destructor.cpp
diff --git a/src/legacy_pointer_safety.cpp b/src/legacy_pointer_safety.cpp
new file mode 100644
index 0000000..34f5613
--- /dev/null
+++ b/src/legacy_pointer_safety.cpp
@@ -0,0 +1,23 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "__config"
+#include <memory>
+
+// Support for garbage collection was removed in C++23 by https://wg21.link/P2186R2. Libc++ implements
+// that removal as an extension in all Standard versions. However, we still define the functions that
+// were once part of the library's ABI for backwards compatibility.
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+_LIBCPP_FUNC_VIS void declare_reachable(void*) {}
+_LIBCPP_FUNC_VIS void declare_no_pointers(char*, size_t) {}
+_LIBCPP_FUNC_VIS void undeclare_no_pointers(char*, size_t) {}
+_LIBCPP_FUNC_VIS void* __undeclare_reachable(void* p) { return p; }
+
+_LIBCPP_END_NAMESPACE_STD
diff --git a/src/memory.cpp b/src/memory.cpp
index 9bd27df..a9b6914 100644
--- a/src/memory.cpp
+++ b/src/memory.cpp
@@ -183,27 +183,6 @@
 
 #endif // !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
 
-void
-declare_reachable(void*)
-{
-}
-
-void
-declare_no_pointers(char*, size_t)
-{
-}
-
-void
-undeclare_no_pointers(char*, size_t)
-{
-}
-
-void*
-__undeclare_reachable(void* p)
-{
-    return p;
-}
-
 void*
 align(size_t alignment, size_t size, void*& ptr, size_t& space)
 {
diff --git a/test/libcxx/diagnostics/detail.headers/memory/pointer_safety.module.verify.cpp b/test/libcxx/diagnostics/detail.headers/memory/pointer_safety.module.verify.cpp
deleted file mode 100644
index 9dd3654..0000000
--- a/test/libcxx/diagnostics/detail.headers/memory/pointer_safety.module.verify.cpp
+++ /dev/null
@@ -1,15 +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
-//
-//===----------------------------------------------------------------------===//
-
-// REQUIRES: modules-build
-
-// WARNING: This test was generated by 'generate_private_header_tests.py'
-// and should not be edited manually.
-
-// expected-error@*:* {{use of private header from outside its module: '__memory/pointer_safety.h'}}
-#include <__memory/pointer_safety.h>
diff --git a/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp b/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp
deleted file mode 100644
index 562f005..0000000
--- a/test/std/utilities/memory/util.dynamic.safety/declare_no_pointers.pass.cpp
+++ /dev/null
@@ -1,28 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03
-
-// <memory>
-
-// void declare_no_pointers(char* p, size_t n);
-// void undeclare_no_pointers(char* p, size_t n);
-
-#include <memory>
-
-#include "test_macros.h"
-
-int main(int, char**)
-{
-    char* p = new char[10];
-    std::declare_no_pointers(p, 10);
-    std::undeclare_no_pointers(p, 10);
-    delete [] p;
-
-  return 0;
-}
diff --git a/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp b/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp
deleted file mode 100644
index 08d06d5..0000000
--- a/test/std/utilities/memory/util.dynamic.safety/declare_reachable.pass.cpp
+++ /dev/null
@@ -1,29 +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
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03
-
-// <memory>
-
-// void declare_reachable(void* p);
-// template <class T> T* undeclare_reachable(T* p);
-
-#include <memory>
-#include <cassert>
-
-#include "test_macros.h"
-
-int main(int, char**)
-{
-    int* p = new int;
-    std::declare_reachable(p);
-    assert(std::undeclare_reachable(p) == p);
-    delete p;
-
-  return 0;
-}
diff --git a/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp b/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
deleted file mode 100644
index e612572..0000000
--- a/test/std/utilities/memory/util.dynamic.safety/get_pointer_safety.pass.cpp
+++ /dev/null
@@ -1,44 +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();
-
-// UNSUPPORTED: c++03
-
-#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);
-  }
-  // Regression test for https://llvm.org/PR26961
-  {
-    std::pointer_safety d;
-    d = std::get_pointer_safety();
-    assert(d == std::get_pointer_safety());
-  }
-
-  return 0;
-}