Skip to content

Commit

Permalink
[libc++] Restore basic_ios's implicit conversion to bool in C++03…
Browse files Browse the repository at this point in the history
… 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

(cherry picked from commit c1a8f12)
  • Loading branch information
Arthur O'Dwyer committed Aug 11, 2021
1 parent 6789c45 commit c85a094
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
7 changes: 7 additions & 0 deletions libcxx/include/ios
Original file line number Diff line number Diff line change
Expand Up @@ -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();}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit c85a094

Please sign in to comment.