[libcxx-commits] [libcxx] c1a8f12 - [libc++] Restore `basic_ios`'s implicit conversion to `bool` in C++03 mode.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Wed Aug 11 10:39:48 PDT 2021


Author: Arthur O'Dwyer
Date: 2021-08-11T13:36:29-04:00
New Revision: c1a8f12873783e8f4827437f6b2dddadfc58109d

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

LOG: [libc++] Restore `basic_ios`'s implicit conversion to `bool` in C++03 mode.

efriedma noted that D104682 broke this test case, reduced from SPEC2006.

    #include <istream>
    bool a(std::istream a) {
        return a.getline(0,0) == 0;
    }

We can unbreak it by restoring the conversion to something-convertible-to-bool.
We chose `void*` in order to match libstdc++.

For more ancient history, see PR19460: https://bugs.llvm.org/show_bug.cgi?id=19460

Differential Revision: https://reviews.llvm.org/D107663

Added: 
    

Modified: 
    libcxx/include/ios
    libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/ios b/libcxx/include/ios
index 3128bca899990..c9230d6a9484a 100644
--- a/libcxx/include/ios
+++ b/libcxx/include/ios
@@ -607,8 +607,15 @@ public:
     static_assert((is_same<_CharT, typename traits_type::char_type>::value),
                   "traits_type::char_type must be the same type as CharT");
 
+#ifdef _LIBCPP_CXX03_LANG
+    // Preserve the ability to compare with literal 0,
+    // and implicitly convert to bool, but not implicitly convert to int.
+    _LIBCPP_INLINE_VISIBILITY
+    operator void*() const {return fail() ? nullptr : (void*)this;}
+#else
     _LIBCPP_INLINE_VISIBILITY
     explicit operator bool() const {return !fail();}
+#endif
 
     _LIBCPP_INLINE_VISIBILITY bool operator!() const    {return  fail();}
     _LIBCPP_INLINE_VISIBILITY iostate rdstate() const   {return ios_base::rdstate();}

diff  --git a/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp b/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp
index 59896c82f29b9..3fe50c6e045f6 100644
--- a/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp
+++ b/libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp
@@ -24,10 +24,16 @@ int main(int, char**)
     assert(static_cast<bool>(ios) == !ios.fail());
     ios.setstate(std::ios::failbit);
     assert(static_cast<bool>(ios) == !ios.fail());
-    static_assert((!std::is_convertible<std::ios, void*>::value), "");
     static_assert((!std::is_convertible<std::ios, int>::value), "");
     static_assert((!std::is_convertible<std::ios const&, int>::value), "");
-    static_assert((!std::is_convertible<std::ios, bool>::value), "");
+#if TEST_STD_VER >= 11
+    static_assert(!std::is_convertible<std::ios, void*>::value, "");
+    static_assert(!std::is_convertible<std::ios, bool>::value, "");
+#else
+    static_assert(std::is_convertible<std::ios, void*>::value, "");
+    static_assert(std::is_convertible<std::ios, bool>::value, "");
+    (void)(ios == 0);  // SPEC2006 apparently relies on this to compile
+#endif
 
   return 0;
 }


        


More information about the libcxx-commits mailing list