From c85a094bcaad233b1a7f029d29f37cfa70ef10c6 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer Date: Fri, 6 Aug 2021 14:50:09 -0400 Subject: [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 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 (cherry picked from commit c1a8f12873783e8f4827437f6b2dddadfc58109d) --- libcxx/include/ios | 7 +++++++ .../iostreams.base/ios/iostate.flags/bool.pass.cpp | 10 ++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'libcxx') diff --git a/libcxx/include/ios b/libcxx/include/ios index 3128bca..c9230d6 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 59896c8..3fe50c6 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(ios) == !ios.fail()); ios.setstate(std::ios::failbit); assert(static_cast(ios) == !ios.fail()); - static_assert((!std::is_convertible::value), ""); static_assert((!std::is_convertible::value), ""); static_assert((!std::is_convertible::value), ""); - static_assert((!std::is_convertible::value), ""); +#if TEST_STD_VER >= 11 + static_assert(!std::is_convertible::value, ""); + static_assert(!std::is_convertible::value, ""); +#else + static_assert(std::is_convertible::value, ""); + static_assert(std::is_convertible::value, ""); + (void)(ios == 0); // SPEC2006 apparently relies on this to compile +#endif return 0; } -- cgit v1.1