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.
---

Tested x86_64-linux.

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

diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index 1c1e1670c33f..61756350cc9c 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -1037,6 +1037,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`.
@@ -1046,7 +1048,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" );
-- 
2.50.1

Reply via email to