
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
163 lines
4.2 KiB
C++
163 lines
4.2 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// <string>
|
|
|
|
// template<class charT, class traits, class Allocator>
|
|
// basic_istream<charT,traits>&
|
|
// getline(basic_istream<charT,traits>& is,
|
|
// basic_string<charT,traits,Allocator>& str);
|
|
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <cassert>
|
|
|
|
#include "min_allocator.h"
|
|
#include "test_macros.h"
|
|
|
|
int main(int, char**)
|
|
{
|
|
{
|
|
std::istringstream in(" abc\n def\n ghij");
|
|
std::string s("initial text");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == " abc");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == " def");
|
|
getline(in, s);
|
|
assert(in.eof());
|
|
assert(s == " ghij");
|
|
}
|
|
{
|
|
std::wistringstream in(L" abc\n def\n ghij");
|
|
std::wstring s(L"initial text");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == L" abc");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == L" def");
|
|
getline(in, s);
|
|
assert(in.eof());
|
|
assert(s == L" ghij");
|
|
}
|
|
#if TEST_STD_VER >= 11
|
|
{
|
|
typedef std::basic_string<char, std::char_traits<char>, min_allocator<char>> S;
|
|
std::istringstream in(" abc\n def\n ghij");
|
|
S s("initial text");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == " abc");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == " def");
|
|
getline(in, s);
|
|
assert(in.eof());
|
|
assert(s == " ghij");
|
|
}
|
|
{
|
|
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, min_allocator<wchar_t>> S;
|
|
std::wistringstream in(L" abc\n def\n ghij");
|
|
S s(L"initial text");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == L" abc");
|
|
getline(in, s);
|
|
assert(in.good());
|
|
assert(s == L" def");
|
|
getline(in, s);
|
|
assert(in.eof());
|
|
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;
|
|
}
|