[libcxx-commits] [libcxx] [libc++] Fix behavior for `get_temporary_buffer` with non-positive size (PR #206871)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jun 30 22:35:46 PDT 2026
https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/206871
>From 92bae65367bbcc5caa6601e70e37715d1bec9e5b Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 1 Jul 2026 10:12:44 +0800
Subject: [PATCH 1/2] [libc++] Fix behavior for `get_temporary_buffer` with
non-positive size
Per C++17 [depr.temporary.buffer]/4, `get_temporary_buffer` is required
to return `{nullptr, 0}` when the size argument is zero or negative.
libc++ used to correctly handle this, but the refactoring in
94e7c0b051c79fd56205f115771980f2e7812306 got this wrong.
---
libcxx/include/__memory/temporary_buffer.h | 3 +++
.../memory/temporary.buffer/overaligned.pass.cpp | 14 ++++++++++++++
.../temporary.buffer/temporary_buffer.pass.cpp | 14 ++++++++++++++
3 files changed, 31 insertions(+)
diff --git a/libcxx/include/__memory/temporary_buffer.h b/libcxx/include/__memory/temporary_buffer.h
index d18717f52d1cd..3c572e43db641 100644
--- a/libcxx/include/__memory/temporary_buffer.h
+++ b/libcxx/include/__memory/temporary_buffer.h
@@ -26,6 +26,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _Tp>
[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_NO_CFI _LIBCPP_DEPRECATED_IN_CXX17 pair<_Tp*, ptrdiff_t>
get_temporary_buffer(ptrdiff_t __n) _NOEXCEPT {
+ if (__n <= 0)
+ return pair<_Tp*, ptrdiff_t>();
+
__unique_temporary_buffer<_Tp> __unique_buf = std::__allocate_unique_temporary_buffer<_Tp>(__n);
pair<_Tp*, ptrdiff_t> __result(__unique_buf.get(), __unique_buf.get_deleter().__count_);
__unique_buf.release();
diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
index 3fa9355270866..678e4e3d342fb 100644
--- a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
+++ b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
@@ -38,5 +38,19 @@ int main(int, char**)
assert(reinterpret_cast<std::uintptr_t>(ip.first) % alignof(A) == 0);
std::return_temporary_buffer(ip.first);
+ // C++17 [depr.temporary.buffer]/4
+ // Returns: If n <= 0 or if no storage could be obtained,
+ // returns a pair P such that P.first is a null pointer value and P.second == 0;
+ {
+ std::pair<A*, std::ptrdiff_t> ret = std::get_temporary_buffer<A>(0);
+ assert(ret.first == NULL);
+ assert(ret.second == 0);
+ }
+ {
+ std::pair<A*, std::ptrdiff_t> ret = std::get_temporary_buffer<A>(-5);
+ assert(ret.first == NULL);
+ assert(ret.second == 0);
+ }
+
return 0;
}
diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
index 39a4767d874e3..50ca6b21ae46c 100644
--- a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
+++ b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
@@ -31,5 +31,19 @@ int main(int, char**)
assert(ip.second == 5);
std::return_temporary_buffer(ip.first);
+ // C++17 [depr.temporary.buffer]/4
+ // Returns: If n <= 0 or if no storage could be obtained,
+ // returns a pair P such that P.first is a null pointer value and P.second == 0;
+ {
+ std::pair<int*, std::ptrdiff_t> ret = std::get_temporary_buffer<int>(0);
+ assert(ret.first == NULL);
+ assert(ret.second == 0);
+ }
+ {
+ std::pair<int*, std::ptrdiff_t> ret = std::get_temporary_buffer<int>(-5);
+ assert(ret.first == NULL);
+ assert(ret.second == 0);
+ }
+
return 0;
}
>From 3794fd647376ff3421a915c4b0d46f6f0263c004 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 1 Jul 2026 13:35:25 +0800
Subject: [PATCH 2/2] `-Wno-alloc-size-larger-than`
---
.../std/utilities/memory/temporary.buffer/overaligned.pass.cpp | 1 +
.../utilities/memory/temporary.buffer/temporary_buffer.pass.cpp | 1 +
2 files changed, 2 insertions(+)
diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
index 678e4e3d342fb..27f9b2a24a9e7 100644
--- a/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
+++ b/libcxx/test/std/utilities/memory/temporary.buffer/overaligned.pass.cpp
@@ -10,6 +10,7 @@
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-alloc-size-larger-than
// <memory>
diff --git a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
index 50ca6b21ae46c..7048bf0fa3c0f 100644
--- a/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
+++ b/libcxx/test/std/utilities/memory/temporary.buffer/temporary_buffer.pass.cpp
@@ -10,6 +10,7 @@
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TEMPORARY_BUFFER
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
+// ADDITIONAL_COMPILE_FLAGS(gcc-style-warnings): -Wno-alloc-size-larger-than
// template <class T>
// pair<T*, ptrdiff_t>
More information about the libcxx-commits
mailing list