aboutsummaryrefslogtreecommitdiff
path: root/libcxx
diff options
context:
space:
mode:
authorArthur O'Dwyer <arthur.j.odwyer@gmail.com>2021-08-06 14:50:09 -0400
committerArthur O'Dwyer <arthur.j.odwyer@gmail.com>2021-08-11 13:40:31 -0400
commitc85a094bcaad233b1a7f029d29f37cfa70ef10c6 (patch)
tree76eaf6e56c86b95c920778d9f1887f63052167fe /libcxx
parent6789c4564a4b33049cb1335d9b8078057af2dc11 (diff)
downloadllvm-c85a094bcaad233b1a7f029d29f37cfa70ef10c6.zip
llvm-c85a094bcaad233b1a7f029d29f37cfa70ef10c6.tar.gz
llvm-c85a094bcaad233b1a7f029d29f37cfa70ef10c6.tar.bz2
[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 (cherry picked from commit c1a8f12873783e8f4827437f6b2dddadfc58109d)
Diffstat (limited to 'libcxx')
-rw-r--r--libcxx/include/ios7
-rw-r--r--libcxx/test/std/input.output/iostreams.base/ios/iostate.flags/bool.pass.cpp10
2 files changed, 15 insertions, 2 deletions
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<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;
}