summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/strings/basic.string/string.nonmembers
diff options
context:
space:
mode:
authorLouis Dionne <ldionne@apple.com>2019-04-02 21:43:07 +0000
committerLouis Dionne <ldionne@apple.com>2019-04-02 21:43:07 +0000
commit1754774369ac8bd5b0d1e0cc88adc4acba9d2666 (patch)
tree555261ab4f3e2950e0d184f7204bd61092e0d7fc /libcxx/test/std/strings/basic.string/string.nonmembers
parentfc5a176f6aae00b2848b337addb87c097a093627 (diff)
downloadbcm5719-llvm-1754774369ac8bd5b0d1e0cc88adc4acba9d2666.tar.gz
bcm5719-llvm-1754774369ac8bd5b0d1e0cc88adc4acba9d2666.zip
[libc++] Fix error flags and exceptions propagated from input stream operations
Summary: Before this patch, we would only ever throw an exception if the badbit was set on the stream. The Standard is currently very unclear on how exceptions should be propagated and what error flags should be set by the input stream operations. This commit changes libc++ to behave under a different (but valid) interpretation of the Standard. This interpretation of the Standard matches what other implementations are doing. I will submit a paper in San Diego to clarify the Standard such that the interpretation used in this commit (and other implementations) is the only possible one. PR21586 PR15949 rdar://problem/15347558 Reviewers: mclow.lists, EricWF Subscribers: christof, dexonsmith, cfe-commits Differential Revision: https://reviews.llvm.org/D49863 llvm-svn: 357531
Diffstat (limited to 'libcxx/test/std/strings/basic.string/string.nonmembers')
-rw-r--r--libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp82
-rw-r--r--libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp81
-rw-r--r--libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp39
3 files changed, 200 insertions, 2 deletions
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp
index 8e663cb4f60..6069f8e377e 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line.pass.cpp
@@ -18,6 +18,7 @@
#include <cassert>
#include "min_allocator.h"
+#include "test_macros.h"
int main(int, char**)
{
@@ -77,6 +78,85 @@ int main(int, char**)
assert(s == L" ghij");
}
#endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ std::basic_stringbuf<char> sb("hello");
+ std::basic_istream<char> is(&sb);
+ is.exceptions(std::ios_base::eofbit);
+
+ std::basic_string<char> s;
+ bool threw = false;
+ try {
+ std::getline(is, s);
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert(!is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == "hello");
+ }
+ {
+ std::basic_stringbuf<wchar_t> sb(L"hello");
+ std::basic_istream<wchar_t> is(&sb);
+ is.exceptions(std::ios_base::eofbit);
+
+ std::basic_string<wchar_t> s;
+ bool threw = false;
+ try {
+ std::getline(is, s);
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert(!is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == L"hello");
+ }
+
+ {
+ std::basic_stringbuf<char> sb;
+ std::basic_istream<char> is(&sb);
+ is.exceptions(std::ios_base::failbit);
+
+ std::basic_string<char> s;
+ bool threw = false;
+ try {
+ std::getline(is, s);
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert( is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == "");
+ }
+ {
+ std::basic_stringbuf<wchar_t> sb;
+ std::basic_istream<wchar_t> is(&sb);
+ is.exceptions(std::ios_base::failbit);
+
+ std::basic_string<wchar_t> s;
+ bool threw = false;
+ try {
+ std::getline(is, s);
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert( is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == L"");
+ }
+#endif // TEST_HAS_NO_EXCEPTIONS
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp
index b081b55c920..d7d271bf02c 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/get_line_delim.pass.cpp
@@ -18,6 +18,7 @@
#include <cassert>
#include "min_allocator.h"
+#include "test_macros.h"
int main(int, char**)
{
@@ -89,6 +90,84 @@ int main(int, char**)
assert(s == L" ghij");
}
#endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ std::basic_stringbuf<char> sb("hello");
+ std::basic_istream<char> is(&sb);
+ is.exceptions(std::ios::eofbit);
+
+ std::basic_string<char> s;
+ bool threw = false;
+ try {
+ std::getline(is, s, '\n');
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert(!is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == "hello");
+ }
+ {
+ std::basic_stringbuf<wchar_t> sb(L"hello");
+ std::basic_istream<wchar_t> is(&sb);
+ is.exceptions(std::ios::eofbit);
+
+ std::basic_string<wchar_t> s;
+ bool threw = false;
+ try {
+ std::getline(is, s, L'\n');
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert(!is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == L"hello");
+ }
+ {
+ std::basic_stringbuf<char> sb;
+ std::basic_istream<char> is(&sb);
+ is.exceptions(std::ios::failbit);
+
+ std::basic_string<char> s;
+ bool threw = false;
+ try {
+ std::getline(is, s, '\n');
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert( is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == "");
+ }
+ {
+ std::basic_stringbuf<wchar_t> sb;
+ std::basic_istream<wchar_t> is(&sb);
+ is.exceptions(std::ios::failbit);
+
+ std::basic_string<wchar_t> s;
+ bool threw = false;
+ try {
+ std::getline(is, s, L'\n');
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert( is.fail());
+ assert( is.eof());
+ assert(threw);
+ assert(s == L"");
+ }
+#endif // TEST_HAS_NO_EXCEPTIONS
- return 0;
+ return 0;
}
diff --git a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp
index 389701d1d51..92061e2c476 100644
--- a/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp
+++ b/libcxx/test/std/strings/basic.string/string.nonmembers/string.io/stream_extract.pass.cpp
@@ -18,6 +18,7 @@
#include <cassert>
#include "min_allocator.h"
+#include "test_macros.h"
int main(int, char**)
{
@@ -65,6 +66,44 @@ int main(int, char**)
in >> s;
assert(in.fail());
}
+#ifndef TEST_HAS_NO_EXCEPTIONS
+ {
+ std::stringbuf sb;
+ std::istream is(&sb);
+ is.exceptions(std::ios::failbit);
+
+ bool threw = false;
+ try {
+ std::string s;
+ is >> s;
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert(is.fail());
+ assert(is.eof());
+ assert(threw);
+ }
+ {
+ std::stringbuf sb;
+ std::istream is(&sb);
+ is.exceptions(std::ios::eofbit);
+
+ bool threw = false;
+ try {
+ std::string s;
+ is >> s;
+ } catch (std::ios::failure const&) {
+ threw = true;
+ }
+
+ assert(!is.bad());
+ assert(is.fail());
+ assert(is.eof());
+ assert(threw);
+ }
+#endif // TEST_HAS_NO_EXCEPTIONS
#if TEST_STD_VER >= 11
{
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
OpenPOWER on IntegriCloud