[libcxx-commits] [libcxx] ab52e9f - [libc++] Add static_assert diagnostics for LWG3133 named requirements (#212360)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Sep 26 09:27:59 PDT 2026


Author: Yordan Vásquez
Date: 2026-09-27T00:27:50+08:00
New Revision: ab52e9f971d626346d70190df72636b477f6c089

URL: https://github.com/llvm/llvm-project/commit/ab52e9f971d626346d70190df72636b477f6c089
DIFF: https://github.com/llvm/llvm-project/commit/ab52e9f971d626346d70190df72636b477f6c089.diff

LOG: [libc++] Add static_assert diagnostics for LWG3133 named requirements (#212360)

Add a static_assert to both std::complex<T> and std::valarray<T>
requiring that T be a cv-unqualified object type that satisfies the
Cpp17DefaultConstructible, Cpp17CopyConstructible, Cpp17CopyAssignable,
and Cpp17Destructible named requirements, per the revised wording in
[numeric.requirements]. This mirrors the existing pattern already used
by std::optional<T>.

Non-_v (class-style) trait forms are used throughout so that the
assertion is well-formed even when <complex>/<valarray> are included in
C++03/11/14 mode.

Test coverage:
- A .verify.cpp for complex<T> and one for valarray<T>, each covering
six failure modes: cv-qualified types, and one type violating each of
the four named requirements individually.

Follows-up e062a29cf865bb7cadea6cb605c9f3515e5b883f.

Added: 
    libcxx/test/std/numerics/complex.number/complex/complex_requires_cv_unqualified_object.verify.cpp
    libcxx/test/std/numerics/numarray/template.valarray/valarray_requires_cv_unqualified_object.verify.cpp

Modified: 
    libcxx/include/complex
    libcxx/include/valarray

Removed: 
    


################################################################################
diff  --git a/libcxx/include/complex b/libcxx/include/complex
index b407bb70156e3..e763688a23bc2 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -267,9 +267,14 @@ template<class T> complex<T> tanh (const complex<T>&);
 #  include <__tuple/tuple_size.h>
 #  include <__type_traits/conditional.h>
 #  include <__type_traits/is_arithmetic.h>
+#  include <__type_traits/is_assignable.h>
+#  include <__type_traits/is_constructible.h>
+#  include <__type_traits/is_destructible.h>
 #  include <__type_traits/is_floating_point.h>
 #  include <__type_traits/is_integral.h>
+#  include <__type_traits/is_object.h>
 #  include <__type_traits/is_same.h>
+#  include <__type_traits/is_unqualified.h>
 #  include <__type_traits/promote.h>
 #  include <__utility/move.h>
 #  include <cmath>
@@ -312,6 +317,12 @@ class complex {
 public:
   typedef _Tp value_type;
 
+  static_assert(is_object<_Tp>::value && __is_unqualified_v<_Tp> && is_default_constructible<_Tp>::value &&
+                    is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value && is_destructible<_Tp>::value,
+                "std::complex<T> requires T to be a cv-unqualified object type that satisfies the "
+                "Cpp17DefaultConstructible, Cpp17CopyConstructible, Cpp17CopyAssignable, and "
+                "Cpp17Destructible requirements");
+
 private:
   value_type __re_;
   value_type __im_;

diff  --git a/libcxx/include/valarray b/libcxx/include/valarray
index d0997ebf2caae..df3ce3252e3d2 100644
--- a/libcxx/include/valarray
+++ b/libcxx/include/valarray
@@ -364,6 +364,11 @@ template<class T> valarray<T> tanh (const valarray<T>& x);
 #  include <__memory/allocator.h>
 #  include <__memory/uninitialized_algorithms.h>
 #  include <__type_traits/decay.h>
+#  include <__type_traits/is_assignable.h>
+#  include <__type_traits/is_constructible.h>
+#  include <__type_traits/is_destructible.h>
+#  include <__type_traits/is_object.h>
+#  include <__type_traits/is_unqualified.h>
 #  include <__type_traits/remove_reference.h>
 #  include <__utility/exception_guard.h>
 #  include <__utility/move.h>
@@ -783,6 +788,12 @@ template <class _Tp>
 class valarray {
 public:
   typedef _Tp value_type;
+
+  static_assert(is_object<_Tp>::value && __is_unqualified_v<_Tp> && is_default_constructible<_Tp>::value &&
+                    is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value && is_destructible<_Tp>::value,
+                "std::valarray<T> requires T to be a cv-unqualified object type that satisfies the "
+                "Cpp17DefaultConstructible, Cpp17CopyConstructible, Cpp17CopyAssignable, and "
+                "Cpp17Destructible requirements");
   typedef _Tp __result_type;
 
   using iterator       = _Tp*;

diff  --git a/libcxx/test/std/numerics/complex.number/complex/complex_requires_cv_unqualified_object.verify.cpp b/libcxx/test/std/numerics/complex.number/complex/complex_requires_cv_unqualified_object.verify.cpp
new file mode 100644
index 0000000000000..146cebd63107e
--- /dev/null
+++ b/libcxx/test/std/numerics/complex.number/complex/complex_requires_cv_unqualified_object.verify.cpp
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <complex>
+
+// template<class T>
+// class complex
+//
+// T shall be a cv-unqualified object type (LWG3133)
+
+#include <complex>
+
+struct NotDefaultConstructible {
+  NotDefaultConstructible() = delete;
+};
+
+struct NotCopyConstructible {
+  NotCopyConstructible()                            = default;
+  NotCopyConstructible(const NotCopyConstructible&) = delete;
+};
+
+struct NotCopyAssignable {
+  NotCopyAssignable()                                    = default;
+  NotCopyAssignable(const NotCopyAssignable&)            = default;
+  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+struct NotDestructible {
+  NotDestructible()                                  = default;
+  NotDestructible(const NotDestructible&)            = default;
+  NotDestructible& operator=(const NotDestructible&) = default;
+
+private:
+  ~NotDestructible() = default;
+};
+
+void test() {
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::complex<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::complex<const double>);
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::complex<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::complex<volatile int>);
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::complex<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::complex<const volatile float>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::complex<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::complex<NotDefaultConstructible>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::complex<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::complex<NotCopyConstructible>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::complex<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::complex<NotCopyAssignable>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::complex<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::complex<NotDestructible>);
+}

diff  --git a/libcxx/test/std/numerics/numarray/template.valarray/valarray_requires_cv_unqualified_object.verify.cpp b/libcxx/test/std/numerics/numarray/template.valarray/valarray_requires_cv_unqualified_object.verify.cpp
new file mode 100644
index 0000000000000..ac7f0a1f7e865
--- /dev/null
+++ b/libcxx/test/std/numerics/numarray/template.valarray/valarray_requires_cv_unqualified_object.verify.cpp
@@ -0,0 +1,62 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// XFAIL: FROZEN-CXX03-HEADERS-FIXME
+
+// <valarray>
+
+// template<class T>
+// class valarray
+//
+// T shall be a cv-unqualified object type that satisfies the Cpp17DefaultConstructible,
+// Cpp17CopyConstructible, Cpp17CopyAssignable, and Cpp17Destructible requirements (LWG3133)
+
+#include <valarray>
+
+struct NotDefaultConstructible {
+  NotDefaultConstructible() = delete;
+};
+
+struct NotCopyConstructible {
+  NotCopyConstructible()                            = default;
+  NotCopyConstructible(const NotCopyConstructible&) = delete;
+};
+
+struct NotCopyAssignable {
+  NotCopyAssignable()                                    = default;
+  NotCopyAssignable(const NotCopyAssignable&)            = default;
+  NotCopyAssignable& operator=(const NotCopyAssignable&) = delete;
+};
+
+struct NotDestructible {
+  NotDestructible()                                  = default;
+  NotDestructible(const NotDestructible&)            = default;
+  NotDestructible& operator=(const NotDestructible&) = default;
+
+private:
+  ~NotDestructible() = default;
+};
+
+void test() {
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::valarray<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::valarray<const int>);
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::valarray<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::valarray<volatile int>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::valarray<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::valarray<NotDefaultConstructible>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::valarray<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::valarray<NotCopyConstructible>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::valarray<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::valarray<NotCopyAssignable>);
+
+  // expected-error-re@*:* {{static assertion failed{{.*}}std::valarray<T> requires T to be a cv-unqualified object type}}
+  (void)sizeof(std::valarray<NotDestructible>);
+}


        


More information about the libcxx-commits mailing list