]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Constrain bitset(const CharT*) constructor [PR121046]
authorJonathan Wakely <jwakely@redhat.com>
Sat, 12 Jul 2025 12:09:03 +0000 (13:09 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 28 Aug 2025 13:00:48 +0000 (14:00 +0100)
Asking std::is_constructible_v<std::bitset<1>, NonTrivial*> gives an
error, rather than answering the query. The problem is that the
constructor for std::bitset("010101") is not constrained to only accept
pointers to char-like types, and for the second parameter (which has a
default argument) std::basic_string_view<CharT> gets instantiated. If
the type is not char-like then that has undefined behaviour, and might
trigger a static_assert to fail in the body of std::basic_string_view.

We can fix it by constraining that constructor using the requirements
for char-like types from [strings.general] p1.  I've submitted LWG 4294
and proposed making this change in the standard.

libstdc++-v3/ChangeLog:

PR libstdc++/121046
* include/std/bitset (bitset(const CharT*, ...)): Add
constraints on CharT type.
* testsuite/23_containers/bitset/lwg4294.cc: New test.

libstdc++-v3/include/std/bitset
libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc [new file with mode: 0644]

index 93a03f6b5d7228c37d1fe989152f5715ca68871f..92f11f19807a31741d54afe2ffd3a0b99e908edb 100644 (file)
@@ -1040,6 +1040,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 #endif
 
 #if __cplusplus >= 201103L
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 4294. bitset(const CharT*) constructor needs to be constrained
       /**
        *  Construct from a character %array.
        *  @param  __str  An %array of characters `__zero` and `__one`.
@@ -1049,7 +1051,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
        *  @throw  std::invalid_argument If a character appears in the string
        *                                which is neither `__zero` nor `__one`.
        */
-      template<typename _CharT>
+      template<typename _CharT,
+              typename = _Require<is_trivially_copyable<_CharT>,
+                                  is_standard_layout<_CharT>,
+                                  is_trivially_default_constructible<_CharT>,
+                                  __not_<is_array<_CharT>>>>
        [[__gnu__::__nonnull__]]
        _GLIBCXX23_CONSTEXPR
         explicit
diff --git a/libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc b/libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc
new file mode 100644 (file)
index 0000000..977555f
--- /dev/null
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+// Bug 121046
+// Asking is_constructible_v<std::bitset<1>, NonTrivial*> is ill-formed
+
+// LWG 4294. bitset(const CharT*) constructor needs to be constrained
+
+#include <bitset>
+struct NonTrivial { ~NonTrivial() { } };
+static_assert( ! std::is_constructible<std::bitset<1>, NonTrivial*>::value,
+              "std::bitset cannot be constructed from this pointer" );