[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