Skip to content

Commit c1a8f12

Browse files
committed
[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
1 parent b2c262c commit c1a8f12

File tree

2 files changed

+15
-2
lines changed
  • libcxx

2 files changed

+15
-2
lines changed

libcxx/include/ios

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,15 @@ public:
607607
static_assert((is_same<_CharT, typename traits_type::char_type>::value),
608608
"traits_type::char_type must be the same type as CharT");
609609

610+
#ifdef _LIBCPP_CXX03_LANG
611+
// Preserve the ability to compare with literal 0,
612+
// and implicitly convert to bool, but not implicitly convert to int.
613+
_LIBCPP_INLINE_VISIBILITY
614+
operator void*() const {return fail() ? nullptr : (void*)this;}
615+
#else
610616
_LIBCPP_INLINE_VISIBILITY
611617
explicit operator bool() const {return !fail();}
618+
#endif
612619

613620
_LIBCPP_INLINE_VISIBILITY bool operator!() const {return fail();}
614621
_LIBCPP_INLINE_VISIBILITY iostate rdstate() const {return ios_base::rdstate();}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ int main(int, char**)
2424
assert(static_cast<bool>(ios) == !ios.fail());
2525
ios.setstate(std::ios::failbit);
2626
assert(static_cast<bool>(ios) == !ios.fail());
27-
static_assert((!std::is_convertible<std::ios, void*>::value), "");
2827
static_assert((!std::is_convertible<std::ios, int>::value), "");
2928
static_assert((!std::is_convertible<std::ios const&, int>::value), "");
30-
static_assert((!std::is_convertible<std::ios, bool>::value), "");
29+
#if TEST_STD_VER >= 11
30+
static_assert(!std::is_convertible<std::ios, void*>::value, "");
31+
static_assert(!std::is_convertible<std::ios, bool>::value, "");
32+
#else
33+
static_assert(std::is_convertible<std::ios, void*>::value, "");
34+
static_assert(std::is_convertible<std::ios, bool>::value, "");
35+
(void)(ios == 0); // SPEC2006 apparently relies on this to compile
36+
#endif
3137

3238
return 0;
3339
}

0 commit comments

Comments
 (0)