[PATCH] libstdc++: check value in std::{con,dis}junction

Alexandre Oliva oliva@adacore.com
Wed Apr 29 19:52:47 GMT 2026


Oops, I forgot to post the following to the libstdc++ mailing list.
https://gcc.gnu.org/pipermail/gcc-patches/2026-April/712661.html

-------------------- Start of forwarded message --------------------
From: Alexandre Oliva <oliva@adacore.com>
To: gcc-patches@gcc.gnu.org
Subject: [PATCH] libstdc++: check value in std::{con,dis}junction
Date: Fri, 10 Apr 2026 09:02:49 -0300


When std::{con,dis}junction is passed a type that doesn't have a
"value" static data member, or whose value doesn't convert to bool, is
ambiguous or inaccessible, we stop iterating over the types and use
that type for the {con,dis}junction, without any diagnostic.

We'd get a diagnostic when attempting to use its value data member as
a bool, but if the member isn't used, compilation is successful,
despite the failure to meet the requirements for "value" in
[meta.logical]/4.

Check that the selected type parameter's value member is convertible
to bool.

Regstrapped on x86_64-linux-gnu.  Ok to install?  Not a regression, so
for stage1 maybe?


for  libstdc++-v3/ChangeLog

	* include/std/type_traits (disjunction, conjunction): Check
	that value converts to bool.
---
 libstdc++-v3/include/std/type_traits               |   15 ++++++++++-
 .../logical_traits/requirements/junction_neg.cc    |   27 ++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/20_util/logical_traits/requirements/junction_neg.cc

diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 59be925e10a6c..238450518c083 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -241,10 +241,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   } // namespace __detail
   /// @endcond
 
+  template<typename _From, typename _To>
+    struct is_convertible;
+
   template<typename... _Bn>
     struct conjunction
     : __detail::__conjunction_impl<void, _Bn...>::type
-    { };
+    {
+      static_assert(is_convertible<decltype(__detail::__conjunction_impl<void, _Bn...>
+					    ::type::value), bool>::value,
+		    "result type's value is not convertible to bool");
+    };
 
   template<>
     struct conjunction<>
@@ -254,7 +261,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename... _Bn>
     struct disjunction
     : __detail::__disjunction_impl<void, _Bn...>::type
-    { };
+    {
+      static_assert(is_convertible<decltype(__detail::__disjunction_impl<void, _Bn...>
+					    ::type::value), bool>::value,
+		    "result type's value is not convertible to bool");
+    };
 
   template<>
     struct disjunction<>
diff --git a/libstdc++-v3/testsuite/20_util/logical_traits/requirements/junction_neg.cc b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/junction_neg.cc
new file mode 100644
index 0000000000000..eb0f246367f11
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/logical_traits/requirements/junction_neg.cc
@@ -0,0 +1,27 @@
+// { dg-do compile { target c++17 } }
+
+#include <type_traits>
+
+class S {}; // not convertible to bool
+
+struct T {
+  static constexpr S value{};
+};
+
+// 4 Every template type argument for which Bi::value is instantiated shall be
+// usable as a base class and shall have a member value which is convertible to
+// bool, is not hidden, and is unambiguously available in the type.
+
+std::conjunction<T> cT; // { dg-error "here" }
+std::conjunction<T, std::true_type> cTt; // { dg-error "here" }
+std::conjunction<T, std::false_type> cTf; // { dg-error "here" }
+std::conjunction<std::true_type, T> ctTtf; // { dg-error "here" }
+std::conjunction<std::false_type, T> cfTtf;
+
+std::disjunction<T> dT; // { dg-error "here" }
+std::disjunction<T, std::true_type> dTt; // { dg-error "here" }
+std::disjunction<T, std::false_type> dTf; // { dg-error "here" }
+std::disjunction<std::false_type, T> dfTtf; // { dg-error "here" }
+std::disjunction<std::true_type, T> dtTtf;
+
+// { dg-prune-output "not convertible to bool|evaluates to false" }

-- 
Alexandre Oliva, happy hacker            https://blog.lx.oliva.nom.br/
Free Software Activist     FSFLA co-founder     GNU Toolchain Engineer
More tolerance and less prejudice are key for inclusion and diversity.
Excluding neuro-others for not behaving ""normal"" is *not* inclusive!
-------------------- End of forwarded message --------------------


More information about the Libstdc++ mailing list