[libcxx-commits] [libcxx] [libc++] Document the strengthened noexcept convention (PR #203869)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 15 03:48:01 PDT 2026


https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/203869

The C++ standard explicitly permits implementations to add `noexcept` to non-virtual library functions whose specification does not require it, and libc++ already does this in many places. Since implementing <expected>, we've been using the "// strengthened" end-of-line comment pattern also used by MSVC to flag places where we strengthen the noexcept specification.

This patch documents that convention in the Coding Guidelines. It also applies the change to a few places to show what that would look like. If we decide to actually commit to this convention, this PR would be ammended to fix them all.

>From cd59049e893e512fe39d4d6f04824a4eb27feb9e Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Mon, 15 Jun 2026 06:38:44 -0400
Subject: [PATCH] [libc++] Document the strengthened noexcept convention

The C++ standard explicitly permits implementations to add `noexcept` to
non-virtual library functions whose specification does not require it,
and libc++ already does this in many places. Since implementing <expected>,
we've been using the "// strengthened" end-of-line comment pattern also
used by MSVC to flag places where we strengthen the noexcept specification.

This patch documents that convention in the Coding Guidelines. It also
applies the change to a few places to show what that would look like.
If we decide to actually commit to this convention, this PR would be
ammended to fix them all.
---
 libcxx/docs/CodingGuidelines.rst         | 19 +++++++++++++++++++
 libcxx/include/__functional/operations.h | 10 +++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/libcxx/docs/CodingGuidelines.rst b/libcxx/docs/CodingGuidelines.rst
index d91e3f22f36b6..94cf59614ef9f 100644
--- a/libcxx/docs/CodingGuidelines.rst
+++ b/libcxx/docs/CodingGuidelines.rst
@@ -225,3 +225,22 @@ after the function they are measuring, with a few transformations to help filter
 When multiple benchmarks measure the same function under different circumstances, we add context as a parenthesis
 after the function signature. For example, ``std::vector<bool>::ctor(Self&&, const allocator_type&) (equal allocators)``
 would be the allocator-aware move constructor for ``std::vector<bool>`` in the case of equal allocators.
+
+Mark strengthened ``noexcept`` specifiers with ``// strengthened``
+==================================================================
+
+The C++ standard explicitly permits implementations to add ``noexcept`` to non-virtual library
+functions whose specification does not require it (`[res.on.exception.handling]/5
+<http://eel.is/c++draft/res.on.exception.handling#5>`_):
+
+  An implementation may strengthen the exception specification for a non-virtual function by
+  adding a non-throwing exception specification.
+
+Every libc++ ``noexcept`` clause that goes beyond what the standard mandates is annotated with an
+end-of-line ``// strengthened`` comment:
+
+.. code-block:: cpp
+
+  _LIBCPP_HIDE_FROM_ABI constexpr expected() noexcept(is_nothrow_default_constructible_v<_Tp>) // strengthened
+    requires is_default_constructible_v<_Tp>
+      : __base(in_place) {}
diff --git a/libcxx/include/__functional/operations.h b/libcxx/include/__functional/operations.h
index 7a80dce648fa1..ae3ed385dc648 100644
--- a/libcxx/include/__functional/operations.h
+++ b/libcxx/include/__functional/operations.h
@@ -54,7 +54,7 @@ template <>
 struct plus<void> {
   template <class _T1, class _T2>
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) //
+      noexcept(noexcept(std::forward<_T1>(__t) + std::forward<_T2>(__u))) // strengthened
       -> decltype(std::forward<_T1>(__t) + std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) + std::forward<_T2>(__u);
   }
@@ -80,7 +80,7 @@ template <>
 struct minus<void> {
   template <class _T1, class _T2>
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) //
+      noexcept(noexcept(std::forward<_T1>(__t) - std::forward<_T2>(__u))) // strengthened
       -> decltype(std::forward<_T1>(__t) - std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) - std::forward<_T2>(__u);
   }
@@ -106,7 +106,7 @@ template <>
 struct multiplies<void> {
   template <class _T1, class _T2>
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) //
+      noexcept(noexcept(std::forward<_T1>(__t) * std::forward<_T2>(__u))) // strengthened
       -> decltype(std::forward<_T1>(__t) * std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) * std::forward<_T2>(__u);
   }
@@ -132,7 +132,7 @@ template <>
 struct divides<void> {
   template <class _T1, class _T2>
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) //
+      noexcept(noexcept(std::forward<_T1>(__t) / std::forward<_T2>(__u))) // strengthened
       -> decltype(std::forward<_T1>(__t) / std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) / std::forward<_T2>(__u);
   }
@@ -158,7 +158,7 @@ template <>
 struct modulus<void> {
   template <class _T1, class _T2>
   _LIBCPP_CONSTEXPR_SINCE_CXX14 _LIBCPP_HIDE_FROM_ABI auto operator()(_T1&& __t, _T2&& __u) const
-      noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) //
+      noexcept(noexcept(std::forward<_T1>(__t) % std::forward<_T2>(__u))) // strengthened
       -> decltype(std::forward<_T1>(__t) % std::forward<_T2>(__u)) {
     return std::forward<_T1>(__t) % std::forward<_T2>(__u);
   }



More information about the libcxx-commits mailing list