https://gcc.gnu.org/g:bbc0e70b610f19320339e4a311591b42bd436e9b

commit r16-3435-gbbc0e70b610f19320339e4a311591b42bd436e9b
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Sat Jul 12 13:09:03 2025 +0100

    libstdc++: Constrain bitset(const CharT*) constructor [PR121046]
    
    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.

Diff:
---
 libstdc++-v3/include/std/bitset                        |  8 +++++++-
 libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc | 11 +++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index 93a03f6b5d72..92f11f19807a 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -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
index 000000000000..977555f9e1fd
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/bitset/lwg4294.cc
@@ -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" );

Reply via email to