[libcxx-commits] [libcxx] [libc++] Implement P2897R7 aligned_accessor: An mdspan accessor expressing pointer over-alignment (PR #122603)

Damien L-G via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jan 31 18:42:35 PST 2025


https://github.com/dalg24 updated https://github.com/llvm/llvm-project/pull/122603

>From 2766103a12489bcbfa75b3df0b6225a35e33543d Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Sat, 11 Jan 2025 13:22:17 -0500
Subject: [PATCH 01/13] [libc++] Implement P2897R7 aligned_accessor: An mdspan
 accessor expressing pointer over-alignment

---
 libcxx/docs/FeatureTestMacroTable.rst         |   4 +
 libcxx/docs/Status/Cxx2cPapers.csv            |   2 +-
 libcxx/include/CMakeLists.txt                 |   2 +
 libcxx/include/__mdspan/aligned_accessor.h    |  86 ++++++++++++++
 libcxx/include/__mdspan/mdspan.h              |   9 +-
 .../__memory/is_sufficiently_aligned.h        |  34 ++++++
 libcxx/include/mdspan                         |  38 ++++++-
 libcxx/include/memory                         |   4 +
 libcxx/include/module.modulemap               |   2 +
 libcxx/modules/std/mdspan.inc                 |   5 +
 libcxx/modules/std/memory.inc                 |   3 +
 .../mdspan/aligned_accessor/access.pass.cpp   |  61 ++++++++++
 .../byte_alignment.verify.cpp                 |  29 +++++
 ....conversion.from.default_accessor.pass.cpp |  81 ++++++++++++++
 .../aligned_accessor/ctor.conversion.pass.cpp | 104 +++++++++++++++++
 .../aligned_accessor/ctor.default.pass.cpp    |  56 ++++++++++
 .../aligned_accessor/element_type.verify.cpp  |  32 ++++++
 .../mdspan/aligned_accessor/offset.pass.cpp   |  61 ++++++++++
 ...or.conversion.to.default_accessor.pass.cpp |  80 +++++++++++++
 .../mdspan/aligned_accessor/types.pass.cpp    |  70 ++++++++++++
 .../is_sufficiently_aligned.pass.cpp          | 105 ++++++++++++++++++
 21 files changed, 862 insertions(+), 6 deletions(-)
 create mode 100644 libcxx/include/__mdspan/aligned_accessor.h
 create mode 100644 libcxx/include/__memory/is_sufficiently_aligned.h
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp
 create mode 100644 libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp
 create mode 100644 libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index cfb0e5cfb129ce..ae8cbe61fd7d17 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -406,6 +406,8 @@ Status
     ----------------------------------------------------------------------------
     ``__cpp_lib_associative_heterogeneous_insertion``          *unimplemented*
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_aligned_accessor``                             ``202411L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_atomic_min_max``                               *unimplemented*
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_bind_front``                                   ``202306L``
@@ -450,6 +452,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_inplace_vector``                               *unimplemented*
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_is_sufficiently_aligned``                      ``202411L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_is_virtual_base_of``                           ``202406L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_is_within_lifetime``                           *unimplemented*
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index aa896e85fcb1fe..ae1f887947fe06 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -81,7 +81,7 @@
 "`P3379R0 <https://wg21.link/P3379R0>`__","Constrain ``std::expected`` equality operators","2024-11 (Wrocław)","","",""
 "`P0472R2 <https://wg21.link/P0472R2>`__","Put ``std::monostate`` in ``<utility>``","2024-11 (Wrocław)","","",""
 "`P2862R1 <https://wg21.link/P2862R1>`__","``text_encoding::name()`` should never return null values","2024-11 (Wrocław)","","",""
-"`P2897R7 <https://wg21.link/P2897R7>`__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","","",""
+"`P2897R7 <https://wg21.link/P2897R7>`__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","|Complete|","20",""
 "`P3355R1 <https://wg21.link/P3355R1>`__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","",""
 "`P3222R0 <https://wg21.link/P3222R0>`__","Fix C++26 by adding transposed special cases for P2642 layouts","2024-11 (Wrocław)","","",""
 "`P3050R2 <https://wg21.link/P3050R2>`__","Fix C++26 by optimizing ``linalg::conjugated`` for noncomplex value types","2024-11 (Wrocław)","","",""
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index f7721b1047b81e..ad7574b8993d08 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -529,6 +529,7 @@ set(files
   __math/traits.h
   __math/trigonometric_functions.h
   __mbstate_t.h
+  __mdspan/aligned_accessor.h
   __mdspan/default_accessor.h
   __mdspan/extents.h
   __mdspan/layout_left.h
@@ -553,6 +554,7 @@ set(files
   __memory/construct_at.h
   __memory/destruct_n.h
   __memory/inout_ptr.h
+  __memory/is_sufficiently_aligned.h
   __memory/noexcept_move_assign_container.h
   __memory/out_ptr.h
   __memory/pointer_traits.h
diff --git a/libcxx/include/__mdspan/aligned_accessor.h b/libcxx/include/__mdspan/aligned_accessor.h
new file mode 100644
index 00000000000000..441c144c11aebb
--- /dev/null
+++ b/libcxx/include/__mdspan/aligned_accessor.h
@@ -0,0 +1,86 @@
+// -*- 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
+//
+//                        Kokkos v. 4.0
+//       Copyright (2022) National Technology & Engineering
+//               Solutions of Sandia, LLC (NTESS).
+//
+// Under the terms of Contract DE-NA0003525 with NTESS,
+// the U.S. Government retains certain rights in this software.
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___MDSPAN_ALIGNED_ACCESSOR_H
+#define _LIBCPP___MDSPAN_ALIGNED_ACCESSOR_H
+
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <__memory/assume_aligned.h>
+#include <__type_traits/is_abstract.h>
+#include <__type_traits/is_array.h>
+#include <__type_traits/is_convertible.h>
+#include <__type_traits/remove_const.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26
+
+template <class _ElementType, size_t _ByteAlignment>
+struct aligned_accessor {
+  static_assert(_ByteAlignment != 0 && (_ByteAlignment & (_ByteAlignment - 1)) == 0,
+                "aligned_accessor: byte alignment must be a power of two");
+  static_assert(_ByteAlignment >= alignof(_ElementType), "aligned_accessor: insufficient byte alignment");
+  static_assert(!is_array_v<_ElementType>, "aligned_accessor: template argument may not be an array type");
+  static_assert(!is_abstract_v<_ElementType>, "aligned_accessor: template argument may not be an abstract class");
+
+  using offset_policy    = default_accessor<_ElementType>;
+  using element_type     = _ElementType;
+  using reference        = _ElementType&;
+  using data_handle_type = _ElementType*;
+
+  static constexpr size_t byte_alignment = _ByteAlignment;
+
+  _LIBCPP_HIDE_FROM_ABI constexpr aligned_accessor() noexcept = default;
+
+  template <class _OtherElementType, size_t _OtherByteAlignment>
+    requires(is_convertible_v<_OtherElementType (*)[], element_type (*)[]> && _OtherByteAlignment >= byte_alignment)
+  _LIBCPP_HIDE_FROM_ABI constexpr aligned_accessor(aligned_accessor<_OtherElementType, _OtherByteAlignment>) noexcept {}
+
+  template <class _OtherElementType>
+    requires(is_convertible_v<_OtherElementType (*)[], element_type (*)[]>)
+  _LIBCPP_HIDE_FROM_ABI explicit constexpr aligned_accessor(default_accessor<_OtherElementType>) noexcept {}
+
+  template <class _OtherElementType>
+    requires(is_convertible_v<element_type (*)[], _OtherElementType (*)[]>)
+  _LIBCPP_HIDE_FROM_ABI constexpr operator default_accessor<_OtherElementType>() const noexcept {
+    return {};
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr reference access(data_handle_type __p, size_t __i) const noexcept {
+    return std::assume_aligned<byte_alignment>(__p)[__i];
+  }
+
+  _LIBCPP_HIDE_FROM_ABI constexpr typename offset_policy::data_handle_type
+  offset(data_handle_type __p, size_t __i) const noexcept {
+    return std::assume_aligned<byte_alignment>(__p) + __i;
+  }
+};
+
+#endif // _LIBCPP_STD_VER >= 26
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___MDSPAN_ALIGNED_ACCESSOR_H
diff --git a/libcxx/include/__mdspan/mdspan.h b/libcxx/include/__mdspan/mdspan.h
index 3f9b35b185b167..ef8db9f1f9789a 100644
--- a/libcxx/include/__mdspan/mdspan.h
+++ b/libcxx/include/__mdspan/mdspan.h
@@ -20,6 +20,7 @@
 #include <__assert>
 #include <__config>
 #include <__fwd/mdspan.h>
+#include <__mdspan/aligned_accessor.h>
 #include <__mdspan/default_accessor.h>
 #include <__mdspan/extents.h>
 #include <__type_traits/extent.h>
@@ -266,13 +267,13 @@ class mdspan {
 #  if _LIBCPP_STD_VER >= 26
 template <class _ElementType, class... _OtherIndexTypes>
   requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0))
-explicit mdspan(_ElementType*,
-                _OtherIndexTypes...) -> mdspan<_ElementType, extents<size_t, __maybe_static_ext<_OtherIndexTypes>...>>;
+explicit mdspan(_ElementType*, _OtherIndexTypes...)
+    -> mdspan<_ElementType, extents<size_t, __maybe_static_ext<_OtherIndexTypes>...>>;
 #  else
 template <class _ElementType, class... _OtherIndexTypes>
   requires((is_convertible_v<_OtherIndexTypes, size_t> && ...) && (sizeof...(_OtherIndexTypes) > 0))
-explicit mdspan(_ElementType*,
-                _OtherIndexTypes...) -> mdspan<_ElementType, dextents<size_t, sizeof...(_OtherIndexTypes)>>;
+explicit mdspan(_ElementType*, _OtherIndexTypes...)
+    -> mdspan<_ElementType, dextents<size_t, sizeof...(_OtherIndexTypes)>>;
 #  endif
 
 template <class _Pointer>
diff --git a/libcxx/include/__memory/is_sufficiently_aligned.h b/libcxx/include/__memory/is_sufficiently_aligned.h
new file mode 100644
index 00000000000000..4280920cabb4bc
--- /dev/null
+++ b/libcxx/include/__memory/is_sufficiently_aligned.h
@@ -0,0 +1,34 @@
+// -*- 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_IS_SUFFICIENTLY_ALIGNED_H
+#define _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H
+
+#include <__config>
+#include <__cstddef/size_t.h>
+#include <cstdint>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26
+
+template <size_t _Alignment, class _Tp>
+_LIBCPP_HIDE_FROM_ABI bool is_sufficiently_aligned(_Tp* __ptr) {
+  return reinterpret_cast<uintptr_t>(__ptr) % _Alignment == 0;
+}
+
+#endif // _LIBCPP_STD_VER >= 26
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___MEMORY_IS_SUFFICIENTLY_ALIGNED_H
diff --git a/libcxx/include/mdspan b/libcxx/include/mdspan
index a67ed1834e3bde..61f1b210dd03af 100644
--- a/libcxx/include/mdspan
+++ b/libcxx/include/mdspan
@@ -33,10 +33,14 @@ namespace std {
   template<class ElementType>
     class default_accessor;
 
+  // [mdspan.accessor.aligned], class template aligned_accessor
+  template<class ElementType, size_t ByteAlignment>
+    class aligned_accessor; // since C++26
+
   // [mdspan.mdspan], class template mdspan
   template<class ElementType, class Extents, class LayoutPolicy = layout_right,
            class AccessorPolicy = default_accessor<ElementType>>
-    class mdspan; // not implemented yet
+    class mdspan;
 }
 
 // extents synopsis
@@ -269,6 +273,38 @@ namespace std {
   };
 }
 
+// aligned_accessor synopsis
+
+namespace std {
+  template<class ElementType, size_t ByteAlignment>
+  struct aligned_accessor {
+    using offset_policy = default_accessor<ElementType>;
+    using element_type = ElementType;
+    using reference = ElementType&;
+    using data_handle_type = ElementType*;
+
+    static constexpr size_t byte_alignment = ByteAlignment;
+
+    constexpr aligned_accessor() noexcept = default;
+
+    template<class OtherElementType, size_t OtherByteAlignment>
+      constexpr aligned_accessor(
+        aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;
+
+    template<class OtherElementType>
+      explicit constexpr aligned_accessor(
+        default_accessor<OtherElementType>) noexcept;
+
+    template<class OtherElementType>
+    constexpr operator default_accessor<OtherElementType>() const noexcept;
+
+    constexpr reference access(data_handle_type p, size_t i) const noexcept;
+
+    constexpr typename offset_policy::data_handle_type
+      offset(data_handle_type p, size_t i) const noexcept;
+  };
+}
+
 // mdspan synopsis
 
 namespace std {
diff --git a/libcxx/include/memory b/libcxx/include/memory
index fc62606ea0fd33..a6400bd29f4437 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -912,6 +912,9 @@ void* align(size_t alignment, size_t size, void*& ptr, size_t& space);
 template<size_t N, class T>
 [[nodiscard]] constexpr T* assume_aligned(T* ptr); // since C++20
 
+template<size_t Alignment, class T>
+  bool is_sufficiently_aligned(T* ptr); // since C++26
+
 // [out.ptr.t], class template out_ptr_t
 template<class Smart, class Pointer, class... Args>
   class out_ptr_t;                                          // since c++23
@@ -945,6 +948,7 @@ template<class Pointer = void, class Smart, class... Args>
 #  include <__memory/allocator_traits.h>
 #  include <__memory/auto_ptr.h>
 #  include <__memory/inout_ptr.h>
+#  include <__memory/is_sufficiently_aligned.h>
 #  include <__memory/out_ptr.h>
 #  include <__memory/pointer_traits.h>
 #  include <__memory/raw_storage_iterator.h>
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 07ab5649ae45cb..c4beb2dfa4f383 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1504,6 +1504,7 @@ module std [system] {
   }
 
   module mdspan {
+    module aligned_accessor   { header "__mdspan/aligned_accessor.h" }
     module default_accessor   { header "__mdspan/default_accessor.h" }
     module extents            { header "__mdspan/extents.h" }
     module fwd                { header "__fwd/mdspan.h" }
@@ -1539,6 +1540,7 @@ module std [system] {
     module destruct_n                         { header "__memory/destruct_n.h" }
     module fwd                                { header "__fwd/memory.h" }
     module inout_ptr                          { header "__memory/inout_ptr.h" }
+    module is_sufficiently_aligned            { header "__memory/is_sufficiently_aligned.h" }
     module noexcept_move_assign_container     { header "__memory/noexcept_move_assign_container.h" }
     module out_ptr                            { header "__memory/out_ptr.h" }
     module pointer_traits                     { header "__memory/pointer_traits.h" }
diff --git a/libcxx/modules/std/mdspan.inc b/libcxx/modules/std/mdspan.inc
index 5e65993383cdc0..c8cc78badb7d59 100644
--- a/libcxx/modules/std/mdspan.inc
+++ b/libcxx/modules/std/mdspan.inc
@@ -28,6 +28,11 @@ export namespace std {
   // [mdspan.accessor.default], class template default_accessor
   using std::default_accessor;
 
+#  if _LIBCPP_STD_VER >= 26
+  // [mdspan.accessor.aligned], class template aligned_accessor
+  using std::aligned_accessor;
+#  endif // _LIBCPP_STD_VER >= 26
+
   // [mdspan.mdspan], class template mdspan
   using std::mdspan;
 #endif // _LIBCPP_STD_VER >= 23
diff --git a/libcxx/modules/std/memory.inc b/libcxx/modules/std/memory.inc
index 82056e426d06c9..c25e9e3443e9cf 100644
--- a/libcxx/modules/std/memory.inc
+++ b/libcxx/modules/std/memory.inc
@@ -17,6 +17,9 @@ export namespace std {
   // [ptr.align], pointer alignment
   using std::align;
   using std::assume_aligned;
+#if _LIBCPP_STD_VER >= 26
+  using std::is_sufficiently_aligned;
+#endif
 
   // [obj.lifetime], explicit lifetime management
   //  using std::start_lifetime_as;
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
new file mode 100644
index 00000000000000..145dc79eda73d4
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+
+// constexpr reference access(data_handle_type p, size_t i) const noexcept;
+//
+// Effects: Equivalent to: return assume_aligned<byte_alignment>(p)[i];
+
+#include <mdspan>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../MinimalElementType.h"
+
+template <class T, size_t N>
+constexpr void test_access() {
+  ElementPool<std::remove_const_t<T>, 10 + N> data;
+  T* ptr = data.get_ptr();
+  std::aligned_accessor<T, N> acc;
+  for (size_t i = 0; i < 10 + N; i++) {
+    if (reinterpret_cast<std::uintptr_t>(ptr + i) % N == 0) {
+      std::same_as<typename std::aligned_accessor<T, N>::reference> decltype(auto) x = acc.access(ptr, i);
+      ASSERT_NOEXCEPT(acc.access(ptr, i));
+      assert(&x == ptr + i);
+    }
+  }
+}
+
+template <class T>
+constexpr void test_it() {
+  constexpr size_t N = alignof(T);
+  test_access<T, N>();
+  test_access<T, 2 * N>();
+  test_access<T, 4 * N>();
+  test_access<T, 8 * N>();
+  test_access<T, 16 * N>();
+}
+
+constexpr bool test() {
+  test_it<int>();
+  test_it<const int>();
+  test_it<MinimalElementType>();
+  test_it<const MinimalElementType>();
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  //static_assert(test());
+  return 0;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
new file mode 100644
index 00000000000000..fbc8386a72dede
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
@@ -0,0 +1,29 @@
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+
+// template<class ElementType, size_t ByteAlignment>
+// class aligned_accessor;
+
+// ByteAlignement is required to be a power of two and greater or equal to alignof(ElementType).
+
+#include <mdspan>
+
+void not_power_of_two() {
+  // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: byte alignment must be a power of two}}
+  [[maybe_unused]] std::aligned_accessor<int, 12> acc;
+}
+
+struct alignas(8) S {};
+
+void insufficiently_aligned() {
+  // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: insufficient byte alignment}}
+  [[maybe_unused]] std::aligned_accessor<S, 4> acc;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp
new file mode 100644
index 00000000000000..339c12bb7c6c54
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp
@@ -0,0 +1,81 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+//
+// template<class OtherElementType>
+//   explicit constexpr aligned_accessor(
+//     default_accessor<OtherElementType>) noexcept {}
+//
+// Constraints: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true.
+
+#include <mdspan>
+#include <cassert>
+#include <cstdint>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../MinimalElementType.h"
+
+struct Base {};
+struct Derived : public Base {};
+
+template <class FromT, class ToT, size_t ToN>
+constexpr void test_conversion() {
+  std::default_accessor<FromT> from;
+  ASSERT_NOEXCEPT(std::aligned_accessor<ToT, ToN>(from));
+  [[maybe_unused]] std::aligned_accessor<ToT, ToN> to(from);
+  // check that the constructor is explicit
+  static_assert(std::is_nothrow_constructible_v<std::aligned_accessor<ToT, ToN>, std::default_accessor<ToT>>);
+  static_assert(!std::is_convertible_v<std::default_accessor<ToT>, std::aligned_accessor<ToT, ToN>>);
+}
+
+template <class From, class To>
+constexpr void test_it() {
+  constexpr size_t N = alignof(To);
+  test_conversion<From, To, N>();
+  test_conversion<From, To, 2 * N>();
+  test_conversion<From, To, 4 * N>();
+  test_conversion<From, To, 8 * N>();
+  test_conversion<From, To, 16 * N>();
+  test_conversion<From, To, 32 * N>();
+}
+
+constexpr bool test() {
+  test_it<int, int>();
+  test_it<int, const int>();
+  test_it<const int, const int>();
+  test_it<MinimalElementType, MinimalElementType>();
+  test_it<MinimalElementType, const MinimalElementType>();
+  test_it<const MinimalElementType, const MinimalElementType>();
+
+  // char is convertible to int, but accessors are not
+  static_assert(!std::is_constructible_v<std::aligned_accessor<int, 4>, std::default_accessor<char>>);
+  // don't allow conversion from const elements to non-const
+  static_assert(!std::is_constructible_v<std::aligned_accessor<int, 4>, std::default_accessor<const int>>);
+  // MinimalElementType is constructible from int, but accessors should not be convertible
+  static_assert(!std::is_constructible_v<std::aligned_accessor<MinimalElementType, 8>, std::default_accessor<int>>);
+  // don't allow conversion from const elements to non-const
+  static_assert(!std::is_constructible_v<std::aligned_accessor<MinimalElementType, 16>,
+                                         std::default_accessor<const MinimalElementType>>);
+  // don't allow conversion from Base to Derived
+  static_assert(!std::is_constructible_v<std::aligned_accessor<Derived, 2>, std::default_accessor<Base>>);
+  // don't allow conversion from Derived to Base
+  static_assert(!std::is_constructible_v<std::aligned_accessor<Base, 2>, std::default_accessor<Derived>>);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp
new file mode 100644
index 00000000000000..0cdfc97dea0aae
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp
@@ -0,0 +1,104 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+//
+// template<class OtherElementType, size_t OtherByteAlignment>
+//   constexpr aligned_accessor(aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept {}
+//
+// Constraints:
+//   - is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true.
+//   - OtherByteAlignment >= byte_alignment is true.
+
+#include <mdspan>
+#include <cassert>
+#include <cstdint>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../MinimalElementType.h"
+
+struct Base {};
+struct Derived : public Base {};
+
+template <class FromT, size_t FromN, class ToT, size_t ToN>
+constexpr void test_conversion() {
+  std::aligned_accessor<FromT, FromN> acc_from;
+  ASSERT_NOEXCEPT(std::aligned_accessor<ToT, ToN>(acc_from));
+  [[maybe_unused]] std::aligned_accessor<ToT, ToN> acc_to(acc_from);
+}
+
+template <class From, class To>
+constexpr void test_it() {
+  constexpr size_t N = alignof(From);
+  static_assert(N == alignof(To));
+
+  test_conversion<From, N, To, N>();
+  test_conversion<From, 2 * N, To, N>();
+  test_conversion<From, 4 * N, To, N>();
+  test_conversion<From, 8 * N, To, N>();
+  test_conversion<From, 16 * N, To, N>();
+  test_conversion<From, 32 * N, To, N>();
+
+  test_conversion<From, 2 * N, To, 2 * N>();
+  test_conversion<From, 4 * N, To, 2 * N>();
+  test_conversion<From, 8 * N, To, 2 * N>();
+  test_conversion<From, 16 * N, To, 2 * N>();
+  test_conversion<From, 32 * N, To, 2 * N>();
+
+  test_conversion<From, 4 * N, To, 4 * N>();
+  test_conversion<From, 8 * N, To, 4 * N>();
+  test_conversion<From, 16 * N, To, 4 * N>();
+  test_conversion<From, 32 * N, To, 4 * N>();
+
+  test_conversion<From, 8 * N, To, 8 * N>();
+  test_conversion<From, 16 * N, To, 8 * N>();
+  test_conversion<From, 32 * N, To, 8 * N>();
+
+  test_conversion<From, 16 * N, To, 16 * N>();
+  test_conversion<From, 32 * N, To, 16 * N>();
+
+  test_conversion<From, 32 * N, To, 32 * N>();
+}
+
+constexpr bool test() {
+  test_it<int, int>();
+  test_it<int, const int>();
+  test_it<const int, const int>();
+  test_it<MinimalElementType, MinimalElementType>();
+  test_it<MinimalElementType, const MinimalElementType>();
+  test_it<const MinimalElementType, const MinimalElementType>();
+
+  // char is convertible to int, but accessors are not
+  static_assert(!std::is_constructible_v<std::aligned_accessor<int, 4>, std::aligned_accessor<char, 4>>);
+  // don't allow conversion from const elements to non-const
+  static_assert(!std::is_constructible_v<std::aligned_accessor<int, 4>, std::aligned_accessor<const int, 4>>);
+  // don't allow conversion from less to more alignment
+  static_assert(!std::is_constructible_v<std::aligned_accessor<int, 8>, std::aligned_accessor<int, 4>>);
+  static_assert(!std::is_constructible_v<std::aligned_accessor<const int, 8>, std::aligned_accessor<const int, 4>>);
+  // MinimalElementType is constructible from int, but accessors should not be convertible
+  static_assert(!std::is_constructible_v<std::aligned_accessor<MinimalElementType, 8>, std::aligned_accessor<int, 8>>);
+  // don't allow conversion from const elements to non-const
+  static_assert(!std::is_constructible_v<std::aligned_accessor<MinimalElementType, 16>,
+                                         std::aligned_accessor<const MinimalElementType, 16>>);
+  // don't allow conversion from Base to Derived
+  static_assert(!std::is_constructible_v<std::aligned_accessor<Derived, 1>, std::aligned_accessor<Base, 1>>);
+  // don't allow conversion from Derived to Base
+  static_assert(!std::is_constructible_v<std::aligned_accessor<Base, 1>, std::aligned_accessor<Derived, 1>>);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp
new file mode 100644
index 00000000000000..4e0b4314c51687
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+
+// Test default construction:
+//
+// constexpr aligned_accessor() noexcept = default;
+
+#include <mdspan>
+#include <cassert>
+#include <cstdint>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../MinimalElementType.h"
+
+template <class T, size_t N>
+constexpr void test_construction() {
+  ASSERT_NOEXCEPT(std::aligned_accessor<T, N>{});
+  [[maybe_unused]] std::aligned_accessor<T, N> acc;
+  static_assert(std::is_trivially_default_constructible_v<std::aligned_accessor<T, N>>);
+}
+
+template <class T>
+constexpr void test_it() {
+  constexpr size_t N = alignof(T);
+  test_construction<T, N>();
+  test_construction<T, 2 * N>();
+  test_construction<T, 4 * N>();
+  test_construction<T, 8 * N>();
+  test_construction<T, 16 * N>();
+  test_construction<T, 32 * N>();
+}
+
+constexpr bool test() {
+  test_it<int>();
+  test_it<const int>();
+  test_it<MinimalElementType>();
+  test_it<const MinimalElementType>();
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
new file mode 100644
index 00000000000000..91510a99aeec9a
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
@@ -0,0 +1,32 @@
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+
+// template<class ElementType, size_t ByteAlignment>
+// class aligned_accessor;
+
+// ElementType is required to be a complete object type that is neither an abstract class type nor an array type.
+
+#include <mdspan>
+
+class AbstractClass {
+public:
+  virtual void method() = 0;
+};
+
+void not_abstract_class() {
+  // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: template argument may not be an abstract class}}
+  [[maybe_unused]] std::aligned_accessor<AbstractClass, 8> acc;
+}
+
+void not_array_type() {
+  // expected-error-re@*:* {{static assertion failed {{.*}}aligned_accessor: template argument may not be an array type}}
+  [[maybe_unused]] std::aligned_accessor<int[5], 128> acc;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
new file mode 100644
index 00000000000000..de6d2c6ebf121c
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+
+// constexpr typename offset_policy::data_handle_type offset(data_handle_type p, size_t i) const noexcept;
+//
+// Effects: Equivalent to: return assume_aligned<byte_alignment>(p) + i;
+
+#include <mdspan>
+#include <cassert>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../MinimalElementType.h"
+
+template <class T, size_t N>
+constexpr void test_offset() {
+  ElementPool<std::remove_const_t<T>, 10 + N> data;
+  T* ptr = data.get_ptr();
+  std::aligned_accessor<T, N> acc;
+  for (size_t i = 0; i < 10 + N; i++) {
+    if (reinterpret_cast<std::uintptr_t>(ptr + i) % N == 0) {
+      static_assert(std::is_same_v<decltype(acc.offset(ptr, i)), typename std::default_accessor<T>::data_handle_type>);
+      ASSERT_NOEXCEPT(acc.offset(ptr, i));
+      assert(acc.offset(ptr, i) == ptr + i);
+    }
+  }
+}
+
+template <class T>
+constexpr void test_it() {
+  constexpr size_t N = alignof(T);
+  test_offset<T, N>();
+  test_offset<T, 2 * N>();
+  test_offset<T, 4 * N>();
+  test_offset<T, 8 * N>();
+  test_offset<T, 16 * N>();
+}
+
+constexpr bool test() {
+  test_it<int>();
+  test_it<const int>();
+  test_it<MinimalElementType>();
+  test_it<const MinimalElementType>();
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  //static_assert(test());
+  return 0;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp
new file mode 100644
index 00000000000000..5b72718c89ec2a
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/operator.conversion.to.default_accessor.pass.cpp
@@ -0,0 +1,80 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+//
+// template<class OtherElementType>
+//   constexpr operator default_accessor<OtherElementType>() const noexcept;
+//
+// Constraints: is_convertible_v<element_type(*)[], OtherElementType(*)[]> is true.
+
+#include <mdspan>
+#include <cassert>
+#include <cstdint>
+#include <type_traits>
+
+#include "test_macros.h"
+
+#include "../MinimalElementType.h"
+
+struct Base {};
+struct Derived : public Base {};
+
+template <class FromT, size_t FromN, class ToT>
+constexpr void test_conversion() {
+  std::aligned_accessor<FromT, FromN> from;
+  ASSERT_NOEXCEPT(std::default_accessor<ToT>(from));
+  [[maybe_unused]] std::default_accessor<ToT> to(from);
+  // check that the conversion is implicit
+  static_assert(std::is_nothrow_convertible_v<std::aligned_accessor<FromT, FromN>, std::default_accessor<ToT>>);
+  static_assert(std::is_nothrow_constructible_v<std::default_accessor<ToT>, std::aligned_accessor<FromT, FromN>>);
+}
+
+template <class From, class To>
+constexpr void test_it() {
+  constexpr size_t N = alignof(From);
+  test_conversion<From, N, To>();
+  test_conversion<From, 2 * N, To>();
+  test_conversion<From, 4 * N, To>();
+  test_conversion<From, 8 * N, To>();
+  test_conversion<From, 16 * N, To>();
+  test_conversion<From, 32 * N, To>();
+}
+
+constexpr bool test() {
+  test_it<int, int>();
+  test_it<int, const int>();
+  test_it<const int, const int>();
+  test_it<MinimalElementType, MinimalElementType>();
+  test_it<MinimalElementType, const MinimalElementType>();
+  test_it<const MinimalElementType, const MinimalElementType>();
+
+  // char is convertible to int, but accessors are not
+  static_assert(!std::is_constructible_v<std::default_accessor<int>, std::aligned_accessor<char, 4>>);
+  // don't allow conversion from const elements to non-const
+  static_assert(!std::is_constructible_v<std::default_accessor<int>, std::aligned_accessor<const int, 8>>);
+  // MinimalElementType is constructible from int, but accessors should not be convertible
+  static_assert(!std::is_constructible_v<std::default_accessor<MinimalElementType>, std::aligned_accessor<int, 4>>);
+  // don't allow conversion from const elements to non-const
+  static_assert(!std::is_constructible_v<std::default_accessor<MinimalElementType>,
+                                         std::aligned_accessor<const MinimalElementType, 4>>);
+  // don't allow conversion from Base to Derived
+  static_assert(!std::is_constructible_v<std::default_accessor<Derived>, std::aligned_accessor<Base, 1>>);
+  // don't allow conversion from Derived to Base
+  static_assert(!std::is_constructible_v<std::default_accessor<Base>, std::aligned_accessor<Derived, 1>>);
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+  static_assert(test());
+  return 0;
+}
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp
new file mode 100644
index 00000000000000..98de91e20c6392
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp
@@ -0,0 +1,70 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// <mdspan>
+
+//  template<class ElementType, size_t ByteAlignment>
+//  struct aligned_accessor {
+//    using offset_policy = default_accessor<ElementType>;
+//    using element_type = ElementType;
+//    using reference = ElementType&;
+//    using data_handle_type = ElementType*;
+//
+//    static constexpr size_t byte_alignment = ByteAlignment;
+//
+//    ...
+//  };
+//
+//  Each specialization of aligned_accessor is a trivially copyable type that models semiregular.
+
+#include <mdspan>
+#include <type_traits>
+#include <concepts>
+#include <cassert>
+
+#include "test_macros.h"
+
+#include "../MinimalElementType.h"
+
+template <class T, size_t N>
+void test_types() {
+  using A = std::aligned_accessor<T, N>;
+  ASSERT_SAME_TYPE(typename A::offset_policy, std::default_accessor<T>);
+  ASSERT_SAME_TYPE(typename A::element_type, T);
+  ASSERT_SAME_TYPE(typename A::reference, T&);
+  ASSERT_SAME_TYPE(typename A::data_handle_type, T*);
+
+  ASSERT_SAME_TYPE(decltype(A::byte_alignment), const size_t);
+  static_assert(A::byte_alignment == N);
+
+  static_assert(std::semiregular<A>);
+  static_assert(std::is_trivially_copyable_v<A>);
+
+  LIBCPP_STATIC_ASSERT(std::is_empty_v<A>);
+}
+
+template <class T>
+constexpr void test() {
+  constexpr size_t N = alignof(T);
+  test_types<T, N>();
+  test_types<T, 2 * N>();
+  test_types<T, 4 * N>();
+  test_types<T, 8 * N>();
+  test_types<T, 16 * N>();
+  test_types<T, 32 * N>();
+}
+
+int main(int, char**) {
+  test<int>();
+  test<const int>();
+  test<MinimalElementType>();
+  test<const MinimalElementType>();
+  return 0;
+}
diff --git a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
new file mode 100644
index 00000000000000..38ca87a3a1771a
--- /dev/null
+++ b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
@@ -0,0 +1,105 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20, c++23
+
+// #include <memory>
+
+// template<size_t Alignment, class T>
+//   bool is_sufficiently_aligned(T* ptr);
+//
+//
+
+#include <cassert>
+#include <cstddef>
+#include <memory>
+
+#include "test_macros.h"
+
+template <typename T>
+constexpr void test_is_sufficiently_aligned() {
+  constexpr std::size_t N = alignof(T);
+
+  alignas(8 * N) std::remove_cv_t<T> buf[5];
+
+  assert(std::is_sufficiently_aligned<N>(&buf[0]));
+  assert(std::is_sufficiently_aligned<2 * N>(&buf[0]));
+  assert(std::is_sufficiently_aligned<4 * N>(&buf[0]));
+  assert(std::is_sufficiently_aligned<8 * N>(&buf[0]));
+
+  assert(std::is_sufficiently_aligned<N>(&buf[1]));
+  assert(!std::is_sufficiently_aligned<2 * N>(&buf[1]));
+  assert(!std::is_sufficiently_aligned<4 * N>(&buf[1]));
+  assert(!std::is_sufficiently_aligned<8 * N>(&buf[1]));
+
+  assert(std::is_sufficiently_aligned<N>(&buf[2]));
+  assert(std::is_sufficiently_aligned<2 * N>(&buf[2]));
+  assert(!std::is_sufficiently_aligned<4 * N>(&buf[2]));
+  assert(!std::is_sufficiently_aligned<8 * N>(&buf[2]));
+
+  assert(std::is_sufficiently_aligned<N>(&buf[3]));
+  assert(!std::is_sufficiently_aligned<2 * N>(&buf[3]));
+  assert(!std::is_sufficiently_aligned<4 * N>(&buf[3]));
+  assert(!std::is_sufficiently_aligned<8 * N>(&buf[3]));
+
+  assert(std::is_sufficiently_aligned<N>(&buf[4]));
+  assert(std::is_sufficiently_aligned<2 * N>(&buf[4]));
+  assert(std::is_sufficiently_aligned<4 * N>(&buf[4]));
+  assert(!std::is_sufficiently_aligned<8 * N>(&buf[4]));
+}
+
+template <typename T>
+constexpr void check(T* p) {
+  ASSERT_SAME_TYPE(bool, decltype(std::is_sufficiently_aligned<alignof(T)>(p)));
+  test_is_sufficiently_aligned<T>();
+  test_is_sufficiently_aligned<const T>();
+}
+
+struct S {};
+struct alignas(4) S4 {};
+struct alignas(8) S8 {};
+struct alignas(16) S16 {};
+struct alignas(32) S32 {};
+struct alignas(64) S64 {};
+struct alignas(128) S128 {};
+
+constexpr bool tests() {
+  char c;
+  int i;
+  long l;
+  double d;
+  long double ld;
+  check(&c);
+  check(&i);
+  check(&l);
+  check(&d);
+  check(&ld);
+
+  S s;
+  S4 s4;
+  S8 s8;
+  S16 s16;
+  S32 s32;
+  S64 s64;
+  S128 s128;
+  check(&s);
+  check(&s4);
+  check(&s8);
+  check(&s16);
+  check(&s32);
+  check(&s64);
+  check(&s128);
+
+  return true;
+}
+
+int main(int, char**) {
+  tests();
+
+  return 0;
+}

>From e36bc1cc588e9c668202e789ee3580819d0c438d Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Sat, 11 Jan 2025 21:42:50 -0500
Subject: [PATCH 02/13] Run the generate scripts

---
 libcxx/docs/FeatureTestMacroTable.rst         |  4 +-
 libcxx/include/version                        |  4 ++
 .../mdspan.version.compile.pass.cpp           | 28 ++++++++++
 .../memory.version.compile.pass.cpp           | 28 ++++++++++
 .../version.version.compile.pass.cpp          | 56 +++++++++++++++++++
 .../generate_feature_test_macro_components.py | 10 ++++
 6 files changed, 128 insertions(+), 2 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index ae8cbe61fd7d17..462b94bc6bc058 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -404,10 +404,10 @@ Status
     ---------------------------------------------------------- -----------------
     **C++26**
     ----------------------------------------------------------------------------
-    ``__cpp_lib_associative_heterogeneous_insertion``          *unimplemented*
-    ---------------------------------------------------------- -----------------
     ``__cpp_lib_aligned_accessor``                             ``202411L``
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_associative_heterogeneous_insertion``          *unimplemented*
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_atomic_min_max``                               *unimplemented*
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_bind_front``                                   ``202306L``
diff --git a/libcxx/include/version b/libcxx/include/version
index f5b5e7a906f504..b81bc3458116b3 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -16,6 +16,7 @@
 Macro name                                              Value   Headers
 __cpp_lib_adaptor_iterator_pair_constructor             202106L <queue> <stack>
 __cpp_lib_addressof_constexpr                           201603L <memory>
+__cpp_lib_aligned_accessor                              202411L <mdspan>
 __cpp_lib_allocate_at_least                             202302L <memory>
 __cpp_lib_allocator_traits_is_always_equal              201411L <deque> <forward_list> <list>
                                                                 <map> <memory> <scoped_allocator>
@@ -145,6 +146,7 @@ __cpp_lib_is_nothrow_convertible                        201806L <type_traits>
 __cpp_lib_is_null_pointer                               201309L <type_traits>
 __cpp_lib_is_pointer_interconvertible                   201907L <type_traits>
 __cpp_lib_is_scoped_enum                                202011L <type_traits>
+__cpp_lib_is_sufficiently_aligned                       202411L <memory>
 __cpp_lib_is_swappable                                  201603L <type_traits>
 __cpp_lib_is_virtual_base_of                            202406L <type_traits>
 __cpp_lib_is_within_lifetime                            202306L <type_traits>
@@ -523,6 +525,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 #endif
 
 #if _LIBCPP_STD_VER >= 26
+# define __cpp_lib_aligned_accessor                     202411L
 // # define __cpp_lib_associative_heterogeneous_insertion  202306L
 // # define __cpp_lib_atomic_min_max                       202403L
 # undef  __cpp_lib_bind_front
@@ -551,6 +554,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 // # define __cpp_lib_generate_random                      202403L
 // # define __cpp_lib_hazard_pointer                       202306L
 // # define __cpp_lib_inplace_vector                       202406L
+# define __cpp_lib_is_sufficiently_aligned              202411L
 # if __has_builtin(__builtin_is_virtual_base_of)
 #   define __cpp_lib_is_virtual_base_of                 202406L
 # endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp
index 64d1c99b223f42..dbba48047949d9 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/mdspan.version.compile.pass.cpp
@@ -16,6 +16,7 @@
 // Test the feature test macros defined by <mdspan>
 
 /*  Constant                         Value
+    __cpp_lib_aligned_accessor       202411L [C++26]
     __cpp_lib_freestanding_mdspan    202311L [C++26]
     __cpp_lib_mdspan                 202207L [C++23]
                                      202406L [C++26]
@@ -27,6 +28,10 @@
 
 #if TEST_STD_VER < 14
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_freestanding_mdspan
 #   error "__cpp_lib_freestanding_mdspan should not be defined before c++26"
 # endif
@@ -41,6 +46,10 @@
 
 #elif TEST_STD_VER == 14
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_freestanding_mdspan
 #   error "__cpp_lib_freestanding_mdspan should not be defined before c++26"
 # endif
@@ -55,6 +64,10 @@
 
 #elif TEST_STD_VER == 17
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_freestanding_mdspan
 #   error "__cpp_lib_freestanding_mdspan should not be defined before c++26"
 # endif
@@ -69,6 +82,10 @@
 
 #elif TEST_STD_VER == 20
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_freestanding_mdspan
 #   error "__cpp_lib_freestanding_mdspan should not be defined before c++26"
 # endif
@@ -83,6 +100,10 @@
 
 #elif TEST_STD_VER == 23
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_freestanding_mdspan
 #   error "__cpp_lib_freestanding_mdspan should not be defined before c++26"
 # endif
@@ -100,6 +121,13 @@
 
 #elif TEST_STD_VER > 23
 
+# ifndef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should be defined in c++26"
+# endif
+# if __cpp_lib_aligned_accessor != 202411L
+#   error "__cpp_lib_aligned_accessor should have the value 202411L in c++26"
+# endif
+
 # if !defined(_LIBCPP_VERSION)
 #   ifndef __cpp_lib_freestanding_mdspan
 #     error "__cpp_lib_freestanding_mdspan should be defined in c++26"
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index 0094bed44be071..5d2ce6042bf6bd 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -25,6 +25,7 @@
     __cpp_lib_constexpr_memory                    201811L [C++20]
                                                   202202L [C++23]
     __cpp_lib_enable_shared_from_this             201603L [C++17]
+    __cpp_lib_is_sufficiently_aligned             202411L [C++26]
     __cpp_lib_make_unique                         201304L [C++14]
     __cpp_lib_out_ptr                             202106L [C++23]
                                                   202311L [C++26]
@@ -78,6 +79,10 @@
 #   error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_make_unique
 #   error "__cpp_lib_make_unique should not be defined before c++14"
 # endif
@@ -152,6 +157,10 @@
 #   error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_make_unique
 #   error "__cpp_lib_make_unique should be defined in c++14"
 # endif
@@ -241,6 +250,10 @@
 #   error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++17"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_make_unique
 #   error "__cpp_lib_make_unique should be defined in c++17"
 # endif
@@ -351,6 +364,10 @@
 #   error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++20"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_make_unique
 #   error "__cpp_lib_make_unique should be defined in c++20"
 # endif
@@ -473,6 +490,10 @@
 #   error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++23"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_make_unique
 #   error "__cpp_lib_make_unique should be defined in c++23"
 # endif
@@ -598,6 +619,13 @@
 #   error "__cpp_lib_enable_shared_from_this should have the value 201603L in c++26"
 # endif
 
+# ifndef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should be defined in c++26"
+# endif
+# if __cpp_lib_is_sufficiently_aligned != 202411L
+#   error "__cpp_lib_is_sufficiently_aligned should have the value 202411L in c++26"
+# endif
+
 # ifndef __cpp_lib_make_unique
 #   error "__cpp_lib_make_unique should be defined in c++26"
 # endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 7c03955df681d5..a8614245028ab7 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -18,6 +18,7 @@
 /*  Constant                                                Value
     __cpp_lib_adaptor_iterator_pair_constructor             202106L [C++23]
     __cpp_lib_addressof_constexpr                           201603L [C++17]
+    __cpp_lib_aligned_accessor                              202411L [C++26]
     __cpp_lib_allocate_at_least                             202302L [C++23]
     __cpp_lib_allocator_traits_is_always_equal              201411L [C++17]
     __cpp_lib_any                                           201606L [C++17]
@@ -132,6 +133,7 @@
     __cpp_lib_is_null_pointer                               201309L [C++14]
     __cpp_lib_is_pointer_interconvertible                   201907L [C++20]
     __cpp_lib_is_scoped_enum                                202011L [C++23]
+    __cpp_lib_is_sufficiently_aligned                       202411L [C++26]
     __cpp_lib_is_swappable                                  201603L [C++17]
     __cpp_lib_is_virtual_base_of                            202406L [C++26]
     __cpp_lib_is_within_lifetime                            202306L [C++26]
@@ -264,6 +266,10 @@
 #   error "__cpp_lib_addressof_constexpr should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_allocate_at_least
 #   error "__cpp_lib_allocate_at_least should not be defined before c++23"
 # endif
@@ -704,6 +710,10 @@
 #   error "__cpp_lib_is_scoped_enum should not be defined before c++23"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_is_swappable
 #   error "__cpp_lib_is_swappable should not be defined before c++17"
 # endif
@@ -1126,6 +1136,10 @@
 #   error "__cpp_lib_addressof_constexpr should not be defined before c++17"
 # endif
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_allocate_at_least
 #   error "__cpp_lib_allocate_at_least should not be defined before c++23"
 # endif
@@ -1590,6 +1604,10 @@
 #   error "__cpp_lib_is_scoped_enum should not be defined before c++23"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_is_swappable
 #   error "__cpp_lib_is_swappable should not be defined before c++17"
 # endif
@@ -2063,6 +2081,10 @@
 #   error "__cpp_lib_addressof_constexpr should have the value 201603L in c++17"
 # endif
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_allocate_at_least
 #   error "__cpp_lib_allocate_at_least should not be defined before c++23"
 # endif
@@ -2611,6 +2633,10 @@
 #   error "__cpp_lib_is_scoped_enum should not be defined before c++23"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_is_swappable
 #   error "__cpp_lib_is_swappable should be defined in c++17"
 # endif
@@ -3195,6 +3221,10 @@
 #   error "__cpp_lib_addressof_constexpr should have the value 201603L in c++20"
 # endif
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifdef __cpp_lib_allocate_at_least
 #   error "__cpp_lib_allocate_at_least should not be defined before c++23"
 # endif
@@ -3914,6 +3944,10 @@
 #   error "__cpp_lib_is_scoped_enum should not be defined before c++23"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_is_swappable
 #   error "__cpp_lib_is_swappable should be defined in c++20"
 # endif
@@ -4594,6 +4628,10 @@
 #   error "__cpp_lib_addressof_constexpr should have the value 201603L in c++23"
 # endif
 
+# ifdef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_allocate_at_least
 #   error "__cpp_lib_allocate_at_least should be defined in c++23"
 # endif
@@ -5388,6 +5426,10 @@
 #   error "__cpp_lib_is_scoped_enum should have the value 202011L in c++23"
 # endif
 
+# ifdef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should not be defined before c++26"
+# endif
+
 # ifndef __cpp_lib_is_swappable
 #   error "__cpp_lib_is_swappable should be defined in c++23"
 # endif
@@ -6215,6 +6257,13 @@
 #   error "__cpp_lib_addressof_constexpr should have the value 201603L in c++26"
 # endif
 
+# ifndef __cpp_lib_aligned_accessor
+#   error "__cpp_lib_aligned_accessor should be defined in c++26"
+# endif
+# if __cpp_lib_aligned_accessor != 202411L
+#   error "__cpp_lib_aligned_accessor should have the value 202411L in c++26"
+# endif
+
 # ifndef __cpp_lib_allocate_at_least
 #   error "__cpp_lib_allocate_at_least should be defined in c++26"
 # endif
@@ -7201,6 +7250,13 @@
 #   error "__cpp_lib_is_scoped_enum should have the value 202011L in c++26"
 # endif
 
+# ifndef __cpp_lib_is_sufficiently_aligned
+#   error "__cpp_lib_is_sufficiently_aligned should be defined in c++26"
+# endif
+# if __cpp_lib_is_sufficiently_aligned != 202411L
+#   error "__cpp_lib_is_sufficiently_aligned should have the value 202411L in c++26"
+# endif
+
 # ifndef __cpp_lib_is_swappable
 #   error "__cpp_lib_is_swappable should be defined in c++26"
 # endif
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index dae827f5de50c2..e35e34bbdd76bc 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -89,6 +89,11 @@ def add_version_header(tc):
             "values": {"c++17": 201603},
             "headers": ["memory"],
         },
+        {
+            "name": "__cpp_lib_aligned_accessor",
+            "values": {"c++26": 202411},
+            "headers": ["mdspan"],
+        },
         {
             "name": "__cpp_lib_allocate_at_least",
             "values": {
@@ -781,6 +786,11 @@ def add_version_header(tc):
             "values": {"c++23": 202011},
             "headers": ["type_traits"],
         },
+        {
+            "name": "__cpp_lib_is_sufficiently_aligned",
+            "values": {"c++26": 202411},
+            "headers": ["memory"],
+        },
         {
             "name": "__cpp_lib_is_swappable",
             "values": {"c++17": 201603},

>From 1c57f2058899cc9ff5f3ecab929a0fe9180464fc Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Sun, 12 Jan 2025 21:49:31 -0500
Subject: [PATCH 03/13] Add missing header include for default_accessor

---
 libcxx/include/__mdspan/aligned_accessor.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/include/__mdspan/aligned_accessor.h b/libcxx/include/__mdspan/aligned_accessor.h
index 441c144c11aebb..2b8d4c52d87374 100644
--- a/libcxx/include/__mdspan/aligned_accessor.h
+++ b/libcxx/include/__mdspan/aligned_accessor.h
@@ -19,6 +19,7 @@
 
 #include <__config>
 #include <__cstddef/size_t.h>
+#include <__mdspan/default_accessor.h>
 #include <__memory/assume_aligned.h>
 #include <__type_traits/is_abstract.h>
 #include <__type_traits/is_array.h>

>From 68ea16753e8303d8015bec1638555f359b52c495 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Sun, 12 Jan 2025 23:53:39 -0500
Subject: [PATCH 04/13] Missing header includes in tests

---
 .../views/mdspan/aligned_accessor/access.pass.cpp           | 2 ++
 .../views/mdspan/aligned_accessor/offset.pass.cpp           | 6 ++++--
 .../memory/ptr.align/is_sufficiently_aligned.pass.cpp       | 1 +
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
index 145dc79eda73d4..40ec85fe56a4dd 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
@@ -16,6 +16,8 @@
 
 #include <mdspan>
 #include <cassert>
+#include <cstdint>
+#include <concepts>
 #include <type_traits>
 
 #include "test_macros.h"
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
index de6d2c6ebf121c..64e37fd7344b27 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
@@ -16,6 +16,8 @@
 
 #include <mdspan>
 #include <cassert>
+#include <cstdint>
+#include <concepts>
 #include <type_traits>
 
 #include "test_macros.h"
@@ -29,9 +31,9 @@ constexpr void test_offset() {
   std::aligned_accessor<T, N> acc;
   for (size_t i = 0; i < 10 + N; i++) {
     if (reinterpret_cast<std::uintptr_t>(ptr + i) % N == 0) {
-      static_assert(std::is_same_v<decltype(acc.offset(ptr, i)), typename std::default_accessor<T>::data_handle_type>);
+      std::same_as<typename std::default_accessor<T>::data_handle_type> decltype(auto) x = acc.offset(ptr, i);
       ASSERT_NOEXCEPT(acc.offset(ptr, i));
-      assert(acc.offset(ptr, i) == ptr + i);
+      assert(x == ptr + i);
     }
   }
 }
diff --git a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
index 38ca87a3a1771a..4616018ef87977 100644
--- a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
+++ b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
@@ -18,6 +18,7 @@
 #include <cassert>
 #include <cstddef>
 #include <memory>
+#include <type_traits>
 
 #include "test_macros.h"
 

>From 1db762c06622806e15ff5fd65b7cfc4bdd607999 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Mon, 13 Jan 2025 13:12:29 -0500
Subject: [PATCH 05/13] Fix access and offset tests

Align the pointer and check 10 elements
---
 .../views/mdspan/aligned_accessor/access.pass.cpp | 15 ++++++++++-----
 .../views/mdspan/aligned_accessor/offset.pass.cpp | 15 ++++++++++-----
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
index 40ec85fe56a4dd..70ccaff779c515 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
@@ -28,14 +28,19 @@ template <class T, size_t N>
 constexpr void test_access() {
   ElementPool<std::remove_const_t<T>, 10 + N> data;
   T* ptr = data.get_ptr();
-  std::aligned_accessor<T, N> acc;
-  for (size_t i = 0; i < 10 + N; i++) {
+  // align ptr
+  for (size_t i = 0; i < N; ++i) {
     if (reinterpret_cast<std::uintptr_t>(ptr + i) % N == 0) {
-      std::same_as<typename std::aligned_accessor<T, N>::reference> decltype(auto) x = acc.access(ptr, i);
-      ASSERT_NOEXCEPT(acc.access(ptr, i));
-      assert(&x == ptr + i);
+      ptr += i;
+      break;
     }
   }
+  std::aligned_accessor<T, N> acc;
+  for (size_t i = 0; i < 10; ++i) {
+    std::same_as<typename std::aligned_accessor<T, N>::reference> decltype(auto) x = acc.access(ptr, i);
+    ASSERT_NOEXCEPT(acc.access(ptr, i));
+    assert(&x == ptr + i);
+  }
 }
 
 template <class T>
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
index 64e37fd7344b27..ae4dac5504f66e 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
@@ -28,14 +28,19 @@ template <class T, size_t N>
 constexpr void test_offset() {
   ElementPool<std::remove_const_t<T>, 10 + N> data;
   T* ptr = data.get_ptr();
-  std::aligned_accessor<T, N> acc;
-  for (size_t i = 0; i < 10 + N; i++) {
+  // align ptr
+  for (size_t i = 0; i < N; ++i) {
     if (reinterpret_cast<std::uintptr_t>(ptr + i) % N == 0) {
-      std::same_as<typename std::default_accessor<T>::data_handle_type> decltype(auto) x = acc.offset(ptr, i);
-      ASSERT_NOEXCEPT(acc.offset(ptr, i));
-      assert(x == ptr + i);
+      ptr += i;
+      break;
     }
   }
+  std::aligned_accessor<T, N> acc;
+  for (size_t i = 0; i < 10; ++i) {
+    std::same_as<typename std::default_accessor<T>::data_handle_type> decltype(auto) x = acc.offset(ptr, i);
+    ASSERT_NOEXCEPT(acc.offset(ptr, i));
+    assert(x == ptr + i);
+  }
 }
 
 template <class T>

>From d2eccee834ddc65ac7c20fb68a93c311b3a07dc6 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 17:27:59 -0500
Subject: [PATCH 06/13] Add a release note

---
 libcxx/docs/ReleaseNotes/21.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index 82f1de6bad3942..f0fcfc5cb57809 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -39,6 +39,7 @@ Implemented Papers
 ------------------
 
 - N4258: Cleaning-up noexcept in the Library (`Github <https://github.com/llvm/llvm-project/issues/99937>`__)
+- P2897R7: ``aligned_accessor``: An mdspan accessor expressing pointer over-alignment (`Github <https://github.com/llvm/llvm-project/issues/118372>`__)
 
 Improvements and New Features
 -----------------------------

>From 64f14e789d727f45355ff6dfdec07662a9e47edf Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 17:32:04 -0500
Subject: [PATCH 07/13] Update release version 20 -> 21

---
 libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index 0c31bb58a1c4a9..f086ec08a005f3 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -81,7 +81,7 @@
 "`P3379R0 <https://wg21.link/P3379R0>`__","Constrain ``std::expected`` equality operators","2024-11 (Wrocław)","","",""
 "`P0472R2 <https://wg21.link/P0472R2>`__","Put ``std::monostate`` in ``<utility>``","2024-11 (Wrocław)","","",""
 "`P2862R1 <https://wg21.link/P2862R1>`__","``text_encoding::name()`` should never return null values","2024-11 (Wrocław)","","",""
-"`P2897R7 <https://wg21.link/P2897R7>`__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","|Complete|","20",""
+"`P2897R7 <https://wg21.link/P2897R7>`__","``aligned_accessor``: An ``mdspan`` accessor expressing pointer over-alignment","2024-11 (Wrocław)","|Complete|","21",""
 "`P3355R1 <https://wg21.link/P3355R1>`__","Fix ``submdspan`` for C++26","2024-11 (Wrocław)","","",""
 "`P3222R0 <https://wg21.link/P3222R0>`__","Fix C++26 by adding transposed special cases for P2642 layouts","2024-11 (Wrocław)","","",""
 "`P3050R2 <https://wg21.link/P3050R2>`__","Fix C++26 by optimizing ``linalg::conjugated`` for noncomplex value types","2024-11 (Wrocław)","","",""

>From baefcf92ae9d67f5c5e22042d83cb9b7fae8c5f7 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 17:35:42 -0500
Subject: [PATCH 08/13] Fix header include <cstd{int -> def}> and qualify
 std::size_t

---
 .../ctor.conversion.from.default_accessor.pass.cpp          | 6 +++---
 .../views/mdspan/aligned_accessor/ctor.conversion.pass.cpp  | 6 +++---
 .../views/mdspan/aligned_accessor/ctor.default.pass.cpp     | 6 +++---
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp
index 339c12bb7c6c54..3c465e89b77b9a 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.from.default_accessor.pass.cpp
@@ -18,7 +18,7 @@
 
 #include <mdspan>
 #include <cassert>
-#include <cstdint>
+#include <cstddef>
 #include <type_traits>
 
 #include "test_macros.h"
@@ -28,7 +28,7 @@
 struct Base {};
 struct Derived : public Base {};
 
-template <class FromT, class ToT, size_t ToN>
+template <class FromT, class ToT, std::size_t ToN>
 constexpr void test_conversion() {
   std::default_accessor<FromT> from;
   ASSERT_NOEXCEPT(std::aligned_accessor<ToT, ToN>(from));
@@ -40,7 +40,7 @@ constexpr void test_conversion() {
 
 template <class From, class To>
 constexpr void test_it() {
-  constexpr size_t N = alignof(To);
+  constexpr std::size_t N = alignof(To);
   test_conversion<From, To, N>();
   test_conversion<From, To, 2 * N>();
   test_conversion<From, To, 4 * N>();
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp
index 0cdfc97dea0aae..0263e7c1d2e3a8 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.conversion.pass.cpp
@@ -19,7 +19,7 @@
 
 #include <mdspan>
 #include <cassert>
-#include <cstdint>
+#include <cstddef>
 #include <type_traits>
 
 #include "test_macros.h"
@@ -29,7 +29,7 @@
 struct Base {};
 struct Derived : public Base {};
 
-template <class FromT, size_t FromN, class ToT, size_t ToN>
+template <class FromT, std::size_t FromN, class ToT, std::size_t ToN>
 constexpr void test_conversion() {
   std::aligned_accessor<FromT, FromN> acc_from;
   ASSERT_NOEXCEPT(std::aligned_accessor<ToT, ToN>(acc_from));
@@ -38,7 +38,7 @@ constexpr void test_conversion() {
 
 template <class From, class To>
 constexpr void test_it() {
-  constexpr size_t N = alignof(From);
+  constexpr std::size_t N = alignof(From);
   static_assert(N == alignof(To));
 
   test_conversion<From, N, To, N>();
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp
index 4e0b4314c51687..a1a2449bd4c679 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/ctor.default.pass.cpp
@@ -16,14 +16,14 @@
 
 #include <mdspan>
 #include <cassert>
-#include <cstdint>
+#include <cstddef>
 #include <type_traits>
 
 #include "test_macros.h"
 
 #include "../MinimalElementType.h"
 
-template <class T, size_t N>
+template <class T, std::size_t N>
 constexpr void test_construction() {
   ASSERT_NOEXCEPT(std::aligned_accessor<T, N>{});
   [[maybe_unused]] std::aligned_accessor<T, N> acc;
@@ -32,7 +32,7 @@ constexpr void test_construction() {
 
 template <class T>
 constexpr void test_it() {
-  constexpr size_t N = alignof(T);
+  constexpr std::size_t N = alignof(T);
   test_construction<T, N>();
   test_construction<T, 2 * N>();
   test_construction<T, 4 * N>();

>From 47d3c567be830ace70ff885087345411f134f61a Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 17:45:58 -0500
Subject: [PATCH 09/13] Move verify tests to test/libcxx/

---
 .../views/mdspan/aligned_accessor/byte_alignment.verify.cpp       | 0
 .../views/mdspan/aligned_accessor/element_type.verify.cpp         | 0
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename libcxx/test/{std => libcxx}/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp (100%)
 rename libcxx/test/{std => libcxx}/containers/views/mdspan/aligned_accessor/element_type.verify.cpp (100%)

diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp b/libcxx/test/libcxx/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
similarity index 100%
rename from libcxx/test/std/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/aligned_accessor/byte_alignment.verify.cpp
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp b/libcxx/test/libcxx/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
similarity index 100%
rename from libcxx/test/std/containers/views/mdspan/aligned_accessor/element_type.verify.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/aligned_accessor/element_type.verify.cpp

>From eda70390adcc52cfdd545f117d6ddc3637144308 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 17:52:29 -0500
Subject: [PATCH 10/13] Drop superfluous constexpr, fix includes, and qualify
 std::size_t

---
 .../views/mdspan/aligned_accessor/types.pass.cpp    | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp
index 98de91e20c6392..1fed971f3bb13a 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/types.pass.cpp
@@ -25,15 +25,16 @@
 //  Each specialization of aligned_accessor is a trivially copyable type that models semiregular.
 
 #include <mdspan>
-#include <type_traits>
-#include <concepts>
 #include <cassert>
+#include <concepts>
+#include <cstddef>
+#include <type_traits>
 
 #include "test_macros.h"
 
 #include "../MinimalElementType.h"
 
-template <class T, size_t N>
+template <class T, std::size_t N>
 void test_types() {
   using A = std::aligned_accessor<T, N>;
   ASSERT_SAME_TYPE(typename A::offset_policy, std::default_accessor<T>);
@@ -41,7 +42,7 @@ void test_types() {
   ASSERT_SAME_TYPE(typename A::reference, T&);
   ASSERT_SAME_TYPE(typename A::data_handle_type, T*);
 
-  ASSERT_SAME_TYPE(decltype(A::byte_alignment), const size_t);
+  ASSERT_SAME_TYPE(decltype(A::byte_alignment), const std::size_t);
   static_assert(A::byte_alignment == N);
 
   static_assert(std::semiregular<A>);
@@ -51,8 +52,8 @@ void test_types() {
 }
 
 template <class T>
-constexpr void test() {
-  constexpr size_t N = alignof(T);
+void test() {
+  constexpr std::size_t N = alignof(T);
   test_types<T, N>();
   test_types<T, 2 * N>();
   test_types<T, 4 * N>();

>From 2cd1d2815ff58131d4a3b899fec3cc8af91382a5 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 17:54:55 -0500
Subject: [PATCH 11/13] Drop stray commented empty lines and superfluous
 constexpr

---
 .../memory/ptr.align/is_sufficiently_aligned.pass.cpp       | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
index 4616018ef87977..7db3e0cf0e6ba1 100644
--- a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
+++ b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
@@ -12,8 +12,6 @@
 
 // template<size_t Alignment, class T>
 //   bool is_sufficiently_aligned(T* ptr);
-//
-//
 
 #include <cassert>
 #include <cstddef>
@@ -23,7 +21,7 @@
 #include "test_macros.h"
 
 template <typename T>
-constexpr void test_is_sufficiently_aligned() {
+void test_is_sufficiently_aligned() {
   constexpr std::size_t N = alignof(T);
 
   alignas(8 * N) std::remove_cv_t<T> buf[5];
@@ -55,7 +53,7 @@ constexpr void test_is_sufficiently_aligned() {
 }
 
 template <typename T>
-constexpr void check(T* p) {
+void check(T* p) {
   ASSERT_SAME_TYPE(bool, decltype(std::is_sufficiently_aligned<alignof(T)>(p)));
   test_is_sufficiently_aligned<T>();
   test_is_sufficiently_aligned<const T>();

>From 8376d2ffcaf2bac6b623b410417bceb4692a1461 Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 18:18:32 -0500
Subject: [PATCH 12/13] Fix access and offset tests to work with constexpr

---
 .../mdspan/aligned_accessor/access.pass.cpp   | 38 ++++++++++---------
 .../mdspan/aligned_accessor/offset.pass.cpp   | 38 ++++++++++---------
 2 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
index 70ccaff779c515..deca1226e47cae 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/access.pass.cpp
@@ -16,27 +16,31 @@
 
 #include <mdspan>
 #include <cassert>
-#include <cstdint>
+#include <cstddef>
 #include <concepts>
 #include <type_traits>
 
 #include "test_macros.h"
 
-#include "../MinimalElementType.h"
+// We are not using MinimalElementType.h because MinimalElementType is not
+// default consructible and uninitialized storage does not work in constexpr.
 
-template <class T, size_t N>
+// Same as MinimalElementType but with a defaulted default constructor
+struct MyMinimalElementType {
+  int val;
+  constexpr MyMinimalElementType()                            = default;
+  constexpr MyMinimalElementType(const MyMinimalElementType&) = delete;
+  constexpr explicit MyMinimalElementType(int v) noexcept : val(v) {}
+  constexpr MyMinimalElementType& operator=(const MyMinimalElementType&) = delete;
+};
+
+template <class T, std::size_t N>
 constexpr void test_access() {
-  ElementPool<std::remove_const_t<T>, 10 + N> data;
-  T* ptr = data.get_ptr();
-  // align ptr
-  for (size_t i = 0; i < N; ++i) {
-    if (reinterpret_cast<std::uintptr_t>(ptr + i) % N == 0) {
-      ptr += i;
-      break;
-    }
-  }
+  constexpr std::size_t Sz = 10;
+  alignas(N) T data[Sz]{};
+  T* ptr = &data[0];
   std::aligned_accessor<T, N> acc;
-  for (size_t i = 0; i < 10; ++i) {
+  for (std::size_t i = 0; i < Sz; ++i) {
     std::same_as<typename std::aligned_accessor<T, N>::reference> decltype(auto) x = acc.access(ptr, i);
     ASSERT_NOEXCEPT(acc.access(ptr, i));
     assert(&x == ptr + i);
@@ -45,7 +49,7 @@ constexpr void test_access() {
 
 template <class T>
 constexpr void test_it() {
-  constexpr size_t N = alignof(T);
+  constexpr std::size_t N = alignof(T);
   test_access<T, N>();
   test_access<T, 2 * N>();
   test_access<T, 4 * N>();
@@ -56,13 +60,13 @@ constexpr void test_it() {
 constexpr bool test() {
   test_it<int>();
   test_it<const int>();
-  test_it<MinimalElementType>();
-  test_it<const MinimalElementType>();
+  test_it<MyMinimalElementType>();
+  test_it<const MyMinimalElementType>();
   return true;
 }
 
 int main(int, char**) {
   test();
-  //static_assert(test());
+  static_assert(test());
   return 0;
 }
diff --git a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
index ae4dac5504f66e..66c30da787a8d3 100644
--- a/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
+++ b/libcxx/test/std/containers/views/mdspan/aligned_accessor/offset.pass.cpp
@@ -16,27 +16,31 @@
 
 #include <mdspan>
 #include <cassert>
-#include <cstdint>
+#include <cstddef>
 #include <concepts>
 #include <type_traits>
 
 #include "test_macros.h"
 
-#include "../MinimalElementType.h"
+// We are not using MinimalElementType.h because MinimalElementType is not
+// default consructible and uninitialized storage does not work in constexpr.
 
-template <class T, size_t N>
+// Same as MinimalElementType but with a defaulted default constructor
+struct MyMinimalElementType {
+  int val;
+  constexpr MyMinimalElementType()                            = default;
+  constexpr MyMinimalElementType(const MyMinimalElementType&) = delete;
+  constexpr explicit MyMinimalElementType(int v) noexcept : val(v) {}
+  constexpr MyMinimalElementType& operator=(const MyMinimalElementType&) = delete;
+};
+
+template <class T, std::size_t N>
 constexpr void test_offset() {
-  ElementPool<std::remove_const_t<T>, 10 + N> data;
-  T* ptr = data.get_ptr();
-  // align ptr
-  for (size_t i = 0; i < N; ++i) {
-    if (reinterpret_cast<std::uintptr_t>(ptr + i) % N == 0) {
-      ptr += i;
-      break;
-    }
-  }
+  constexpr std::size_t Sz = 10;
+  alignas(N) T data[Sz]{};
+  T* ptr = &data[0];
   std::aligned_accessor<T, N> acc;
-  for (size_t i = 0; i < 10; ++i) {
+  for (std::size_t i = 0; i < Sz; ++i) {
     std::same_as<typename std::default_accessor<T>::data_handle_type> decltype(auto) x = acc.offset(ptr, i);
     ASSERT_NOEXCEPT(acc.offset(ptr, i));
     assert(x == ptr + i);
@@ -45,7 +49,7 @@ constexpr void test_offset() {
 
 template <class T>
 constexpr void test_it() {
-  constexpr size_t N = alignof(T);
+  constexpr std::size_t N = alignof(T);
   test_offset<T, N>();
   test_offset<T, 2 * N>();
   test_offset<T, 4 * N>();
@@ -56,13 +60,13 @@ constexpr void test_it() {
 constexpr bool test() {
   test_it<int>();
   test_it<const int>();
-  test_it<MinimalElementType>();
-  test_it<const MinimalElementType>();
+  test_it<MyMinimalElementType>();
+  test_it<const MyMinimalElementType>();
   return true;
 }
 
 int main(int, char**) {
   test();
-  //static_assert(test());
+  static_assert(test());
   return 0;
 }

>From a863a600b17a14c69921105e97e877b17f38ee7f Mon Sep 17 00:00:00 2001
From: Damien L-G <dalg24 at gmail.com>
Date: Fri, 31 Jan 2025 21:41:34 -0500
Subject: [PATCH 13/13] Correct oversight stray constexpr

---
 .../utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
index 7db3e0cf0e6ba1..139767d40af3b1 100644
--- a/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
+++ b/libcxx/test/std/utilities/memory/ptr.align/is_sufficiently_aligned.pass.cpp
@@ -67,7 +67,7 @@ struct alignas(32) S32 {};
 struct alignas(64) S64 {};
 struct alignas(128) S128 {};
 
-constexpr bool tests() {
+bool tests() {
   char c;
   int i;
   long l;



More information about the libcxx-commits mailing list