[libcxx-commits] [libcxx] [libc++] Add missing noexcept on shared_ptr assignment (PR #219533)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Aug 28 10:04:10 PDT 2026
https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/219533
The Standard declares it as noexcept in [util.smartptr.shared.assign]. Also add a couple of missing tests.
>From 6dd55c4e17446a174c8e854ec92c4e3a9f17f285 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Tue, 16 Jun 2026 14:01:07 -0400
Subject: [PATCH] [libc++] Add missing noexcept on shared_ptr assignment
The Standard declares it as noexcept in [util.smartptr.shared.assign].
Also add a couple of missing tests.
---
libcxx/include/__memory/shared_ptr.h | 2 +-
libcxx/include/memory | 2 +-
.../util.smartptr.shared.assign/shared_ptr.pass.cpp | 4 +++-
.../util.smartptr.shared.assign/shared_ptr_Y.pass.cpp | 4 +++-
.../util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp | 4 +++-
.../util.smartptr.shared.assign/shared_ptr_rv.pass.cpp | 4 +++-
6 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 7d8a0d27739a0..5386eb29e58a2 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -474,7 +474,7 @@ class _LIBCPP_SHARED_PTR_TRIVIAL_ABI shared_ptr {
}
template <class _Yp, __enable_if_t<__compatible_with_v<_Yp, _Tp>, int> = 0>
- _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r) {
+ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r) _NOEXCEPT {
shared_ptr(std::move(__r)).swap(*this);
return *this;
}
diff --git a/libcxx/include/memory b/libcxx/include/memory
index e1e2e801a07ab..f1529a1c0f884 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -613,7 +613,7 @@ public:
shared_ptr& operator=(const shared_ptr& r) noexcept;
template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
shared_ptr& operator=(shared_ptr&& r) noexcept;
- template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
+ template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
template<class Y> shared_ptr& operator=(auto_ptr<Y>&& r); // removed in C++17
template <class Y, class D> shared_ptr& operator=(unique_ptr<Y, D>&& r);
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr.pass.cpp
index 7bf1501d1bcd2..79126748fac52 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr.pass.cpp
@@ -10,7 +10,7 @@
// shared_ptr
-// shared_ptr& operator=(const shared_ptr& r);
+// shared_ptr& operator=(const shared_ptr& r) noexcept;
// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS
@@ -45,6 +45,8 @@ int A::count = 0;
int main(int, char**)
{
+ static_assert(std::is_nothrow_assignable<std::shared_ptr<A>&, const std::shared_ptr<A>&>::value, "");
+
{
const std::shared_ptr<A> pA(new A);
A* ptrA = pA.get();
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y.pass.cpp
index 9b7e43ff65af4..1a09f364cb2aa 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y.pass.cpp
@@ -10,7 +10,7 @@
// shared_ptr
-// template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r);
+// template<class Y> shared_ptr& operator=(const shared_ptr<Y>& r) noexcept;
#include <memory>
#include <type_traits>
@@ -43,6 +43,8 @@ int A::count = 0;
int main(int, char**)
{
+ static_assert(std::is_nothrow_assignable<std::shared_ptr<B>&, const std::shared_ptr<A>&>::value, "");
+
{
const std::shared_ptr<A> pA(new A);
A* ptrA = pA.get();
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp
index 2a0a523592487..3cf084f667a93 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_Y_rv.pass.cpp
@@ -12,7 +12,7 @@
// shared_ptr
-// template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r);
+// template<class Y> shared_ptr& operator=(shared_ptr<Y>&& r) noexcept;
#include <memory>
#include <type_traits>
@@ -46,6 +46,8 @@ int A::count = 0;
int main(int, char**)
{
+ static_assert(std::is_nothrow_assignable<std::shared_ptr<B>&, std::shared_ptr<A>&&>::value, "");
+
{
std::shared_ptr<A> pA(new A);
A* ptrA = pA.get();
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp
index f48fe75447eed..7a952f6138bd5 100644
--- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp
+++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.assign/shared_ptr_rv.pass.cpp
@@ -12,7 +12,7 @@
// shared_ptr
-// shared_ptr& operator=(shared_ptr&& r);
+// shared_ptr& operator=(shared_ptr&& r) noexcept;
#include <memory>
#include <type_traits>
@@ -46,6 +46,8 @@ int A::count = 0;
int main(int, char**)
{
+ static_assert(std::is_nothrow_assignable<std::shared_ptr<A>&, std::shared_ptr<A>&&>::value, "");
+
{
std::shared_ptr<A> pA(new A);
A* ptrA = pA.get();
More information about the libcxx-commits
mailing list