[gcc r16-7987] libstdc++: Constrain std::as_bytes to disallow span<volatile T>
Jonathan Wakely
redi@gcc.gnu.org
Tue Mar 10 18:22:07 GMT 2026
https://gcc.gnu.org/g:a4f807e74118302319ec99adefd0646a9e7a1d34
commit r16-7987-ga4f807e74118302319ec99adefd0646a9e7a1d34
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Mar 10 16:00:40 2026 +0000
libstdc++: Constrain std::as_bytes to disallow span<volatile T>
Implement the accepted resolution of LWG 4243, approved in Kona 2025.
libstdc++-v3/ChangeLog:
* include/std/span (as_bytes, as_writable_bytes): Add
constraints to disallow volatile elements, as per LWG 4243.
* testsuite/23_containers/span/lwg4243.cc: New test.
Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
Diff:
---
libstdc++-v3/include/std/span | 5 +++-
.../testsuite/23_containers/span/lwg4243.cc | 31 ++++++++++++++++++++++
2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/libstdc++-v3/include/std/span b/libstdc++-v3/include/std/span
index 8f525d009ff5..a2f338449c8a 100644
--- a/libstdc++-v3/include/std/span
+++ b/libstdc++-v3/include/std/span
@@ -517,7 +517,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
span(_Range &&)
-> span<remove_reference_t<ranges::range_reference_t<_Range&>>>;
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4243. as_bytes/as_writable_bytes is broken with span<volatile T>
template<typename _Type, size_t _Extent>
+ requires (!is_volatile_v<_Type>)
[[nodiscard]]
inline
span<const byte, _Extent == dynamic_extent
@@ -532,7 +535,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _Type, size_t _Extent>
- requires (!is_const_v<_Type>)
+ requires (!is_const_v<_Type> && !is_volatile_v<_Type>)
inline
span<byte, _Extent == dynamic_extent
? dynamic_extent : _Extent * sizeof(_Type)>
diff --git a/libstdc++-v3/testsuite/23_containers/span/lwg4243.cc b/libstdc++-v3/testsuite/23_containers/span/lwg4243.cc
new file mode 100644
index 000000000000..26bb53d8739b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/lwg4243.cc
@@ -0,0 +1,31 @@
+// { dg-do compile { target c++20 } }
+
+// LWG 4243. as_bytes/as_writable_bytes is broken with span<volatile T>
+
+#include <span>
+
+template<typename ElementType, std::size_t Extent = std::dynamic_extent>
+concept can_call_as_bytes
+ = requires (std::span<ElementType, Extent> s) { std::as_bytes(s); };
+
+static_assert( can_call_as_bytes<int> );
+static_assert( can_call_as_bytes<int, 10> );
+static_assert( can_call_as_bytes<const int> );
+static_assert( can_call_as_bytes<const int, 10> );
+static_assert( ! can_call_as_bytes<volatile int> );
+static_assert( ! can_call_as_bytes<volatile int, 10> );
+static_assert( ! can_call_as_bytes<const volatile int> );
+static_assert( ! can_call_as_bytes<const volatile int, 10> );
+
+template<typename ElementType, std::size_t Extent = std::dynamic_extent>
+concept can_call_as_writable_bytes
+ = requires (std::span<ElementType, Extent> s) { std::as_writable_bytes(s); };
+
+static_assert( can_call_as_writable_bytes<int> );
+static_assert( can_call_as_writable_bytes<int, 10> );
+static_assert( ! can_call_as_writable_bytes<const int> );
+static_assert( ! can_call_as_writable_bytes<const int, 10> );
+static_assert( ! can_call_as_writable_bytes<volatile int> );
+static_assert( ! can_call_as_writable_bytes<volatile int, 10> );
+static_assert( ! can_call_as_writable_bytes<const volatile int> );
+static_assert( ! can_call_as_writable_bytes<const volatile int, 10> );
More information about the Libstdc++-cvs
mailing list