Remove workaround for GCC Bug 66145
This commit is contained in:
parent
2f141adb6f
commit
132f936c57
|
@ -24,7 +24,6 @@ set(HEADER_FILES
|
|||
io/copy.h
|
||||
io/inifile.h
|
||||
io/path.h
|
||||
io/catchiofailure.h
|
||||
io/nativefilestream.h
|
||||
io/misc.h
|
||||
math/math.h
|
||||
|
@ -52,7 +51,6 @@ set(SRC_FILES
|
|||
io/bitreader.cpp
|
||||
io/inifile.cpp
|
||||
io/path.cpp
|
||||
io/catchiofailure.cpp
|
||||
io/nativefilestream.cpp
|
||||
io/misc.cpp
|
||||
math/math.cpp
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "./bitreader.h"
|
||||
#include "./catchiofailure.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -22,7 +21,7 @@ void BitReader::skipBits(std::size_t bitCount)
|
|||
m_bitsAvail -= bitCount;
|
||||
} else {
|
||||
if ((m_buffer += 1 + (bitCount -= m_bitsAvail) / 8) >= m_end) {
|
||||
throwIoFailure("end of buffer exceeded");
|
||||
throw ios_base::failure("end of buffer exceeded");
|
||||
}
|
||||
m_bitsAvail = 8 - (bitCount % 8);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "../conversion/types.h"
|
||||
#include "../global.h"
|
||||
#include "../io/catchiofailure.h"
|
||||
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
|
@ -71,7 +70,7 @@ template <typename intType> intType BitReader::readBits(byte bitCount)
|
|||
for (byte readAtOnce; bitCount; bitCount -= readAtOnce) {
|
||||
if (!m_bitsAvail) {
|
||||
if (++m_buffer >= m_end) {
|
||||
throwIoFailure("end of buffer exceeded");
|
||||
throw std::ios_base::failure("end of buffer exceeded");
|
||||
}
|
||||
m_bitsAvail = 8;
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
#define _GLIBCXX_USE_CXX11_ABI 0
|
||||
// include libstdc++ specific header <bits/c++config.h> containing __GLIBCXX__
|
||||
// without including ios already (must be included after setting _GLIBCXX_USE_CXX11_ABI)
|
||||
#include <cstddef>
|
||||
|
||||
// ensure the old ABI is used under libstd++ < 7 and the new ABI under libstd++ >= 7
|
||||
// (because libstdc++ < 7 throws the old ios_base::failure and libstdc++ >= 7 the new one)
|
||||
#if defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE >= 7
|
||||
#undef _GLIBCXX_USE_CXX11_ABI
|
||||
#define _GLIBCXX_USE_CXX11_ABI 1
|
||||
#endif
|
||||
|
||||
#include "./catchiofailure.h"
|
||||
|
||||
#include <ios>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace IoUtilities {
|
||||
|
||||
/*!
|
||||
* \brief Provides a workaround for GCC Bug 66145.
|
||||
* \returns Returns the error message.
|
||||
* \throws Throws the current exception if it is not std::ios_base::failure.
|
||||
* \remarks
|
||||
* - GCC Bug 66145 is "resolved", but the story continues with GCC Bug 85222.
|
||||
* - However, the bug finally got fixed for 7.4 and 8.1 so this workaround can be
|
||||
* dropped in the next major release which also drops support for older libstdc++
|
||||
* versions.
|
||||
* \sa
|
||||
* - initial bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145
|
||||
* - change introduced in libstdc++ 7: https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/src/c%2B%2B11/functexcept.cc?r1=244498&r2=244497&pathrev=244498
|
||||
* - follow-up bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85222
|
||||
* - final fix: https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=259352
|
||||
*/
|
||||
const char *catchIoFailure()
|
||||
{
|
||||
try {
|
||||
throw;
|
||||
} catch (const ios_base::failure &e) {
|
||||
return e.what();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Throws an std::ios_base::failure with the specified message.
|
||||
* \sa catchIoFailure()
|
||||
*/
|
||||
void throwIoFailure(const char *what)
|
||||
{
|
||||
throw ios_base::failure(what);
|
||||
}
|
||||
} // namespace IoUtilities
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef IOUTILITIES_CATCHIOFAILURE_H
|
||||
#define IOUTILITIES_CATCHIOFAILURE_H
|
||||
|
||||
#include "../global.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace IoUtilities {
|
||||
|
||||
CPP_UTILITIES_EXPORT const char *catchIoFailure();
|
||||
[[noreturn]] CPP_UTILITIES_EXPORT void throwIoFailure(const char *what);
|
||||
} // namespace IoUtilities
|
||||
|
||||
#endif // IOUTILITIES_CATCHIOFAILURE_H
|
|
@ -1,5 +1,4 @@
|
|||
#include "./inifile.h"
|
||||
#include "./catchiofailure.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
@ -135,15 +134,13 @@ void IniFile::parse(std::istream &inputStream)
|
|||
break;
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
const char *what = catchIoFailure();
|
||||
if (inputStream.eof()) {
|
||||
// we just reached the end of the file
|
||||
// don't forget to save the last key/value pair
|
||||
finishKeyValue();
|
||||
} else {
|
||||
throwIoFailure(what);
|
||||
} catch (const std::ios_base::failure &) {
|
||||
if (!inputStream.eof()) {
|
||||
throw;
|
||||
}
|
||||
// we just reached the end of the file
|
||||
// don't forget to save the last key/value pair
|
||||
finishKeyValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "./misc.h"
|
||||
#include "./catchiofailure.h"
|
||||
#include "./nativefilestream.h"
|
||||
|
||||
#include <streambuf>
|
||||
|
@ -22,7 +21,7 @@ string readFile(const string &path, std::string::size_type maxSize)
|
|||
string res;
|
||||
const auto size = static_cast<string::size_type>(file.tellg());
|
||||
if (maxSize != string::npos && size > maxSize) {
|
||||
throwIoFailure("File exceeds max size");
|
||||
throw ios_base::failure("File exceeds max size");
|
||||
}
|
||||
res.reserve(size);
|
||||
file.seekg(ios_base::beg);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "./nativefilestream.h"
|
||||
|
||||
#ifdef CPP_UTILITIES_USE_NATIVE_FILE_BUFFER
|
||||
#include "./catchiofailure.h"
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
#include "../conversion/stringconversion.h"
|
||||
|
@ -143,9 +142,6 @@ NativeFileStream::NativeFileStream()
|
|||
NativeFileStream::NativeFileStream(NativeFileStream &&other)
|
||||
: iostream(other.m_filebuf.release())
|
||||
, m_filebuf(rdbuf())
|
||||
#if !defined(__ANDROID_API__) || !defined(__ANDROID_API_N__) || (__ANDROID_API__ < __ANDROID_API_N__)
|
||||
, m_fileHandle(other.m_fileHandle)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -231,12 +227,12 @@ std::unique_ptr<std::basic_streambuf<char>> NativeFileStream::makeFileBuffer(con
|
|||
#ifdef PLATFORM_WINDOWS
|
||||
const int fileHandle = _wopen(widePath.get(), nativeParams.openMode, nativeParams.permissions);
|
||||
if (fileHandle == -1) {
|
||||
::IoUtilities::throwIoFailure("_wopen failed");
|
||||
throw std::ios_base::failure("_wopen failed");
|
||||
}
|
||||
#else
|
||||
const auto fileHandle = fopen(path.data(), nativeParams.openMode.data());
|
||||
if (!fileHandle) {
|
||||
::IoUtilities::throwIoFailure("fopen failed");
|
||||
throw std::ios_base::failure("fopen failed");
|
||||
}
|
||||
#endif
|
||||
return make_unique<StreamBuffer>(fileHandle, openMode);
|
||||
|
@ -247,12 +243,12 @@ std::unique_ptr<std::basic_streambuf<char>> NativeFileStream::makeFileBuffer(con
|
|||
const auto fileDescriptor
|
||||
= CreateFileW(widePath.get(), nativeParams.access, nativeParams.shareMode, nullptr, nativeParams.creation, FILE_ATTRIBUTE_NORMAL);
|
||||
if (fileDescriptor == INVALID_HANDLE_VALUE) {
|
||||
::IoUtilities::throwIoFailure("CreateFileW failed");
|
||||
throw std::ios_base::failure("CreateFileW failed");
|
||||
}
|
||||
#else
|
||||
const auto fileDescriptor = ::open(path.data(), nativeParams.openFlags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (fileDescriptor == -1) {
|
||||
::IoUtilities::throwIoFailure("open failed");
|
||||
throw std::ios_base::failure("open failed");
|
||||
}
|
||||
#endif
|
||||
return make_unique<StreamBuffer>(fileDescriptor, boost::iostreams::close_handle);
|
||||
|
@ -272,16 +268,16 @@ std::unique_ptr<std::basic_streambuf<char>> NativeFileStream::makeFileBuffer(int
|
|||
#ifdef PLATFORM_WINDOWS
|
||||
const auto fileHandle = _get_osfhandle(fileDescriptor);
|
||||
if (fileHandle == -1) {
|
||||
::IoUtilities::throwIoFailure("_get_osfhandle failed");
|
||||
throw std::ios_base::failure("_get_osfhandle failed");
|
||||
}
|
||||
const auto osFileHandle = _open_osfhandle(fileHandle, nativeParams.flags);
|
||||
if (osFileHandle == -1) {
|
||||
::IoUtilities::throwIoFailure("_open_osfhandle failed");
|
||||
throw std::ios_base::failure("_open_osfhandle failed");
|
||||
}
|
||||
#else
|
||||
const auto fileHandle = fdopen(fileDescriptor, nativeParams.openMode.data());
|
||||
if (!fileHandle) {
|
||||
::IoUtilities::throwIoFailure("fdopen failed");
|
||||
throw std::ios_base::failure("fdopen failed");
|
||||
}
|
||||
#endif
|
||||
return make_unique<StreamBuffer>(fileDescriptor, openMode);
|
||||
|
@ -301,7 +297,7 @@ std::unique_ptr<wchar_t[]> NativeFileStream::makeWidePath(const std::string &pat
|
|||
{
|
||||
auto widePath = ::ConversionUtilities::convertMultiByteToWide(path);
|
||||
if (!widePath.first) {
|
||||
::IoUtilities::throwIoFailure("Unable to convert path to UTF-16");
|
||||
throw std::ios_base::failure("Unable to convert path to UTF-16");
|
||||
}
|
||||
return std::move(widePath.first);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include <memory>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#else
|
||||
#endif
|
||||
#include <fstream>
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "../io/binaryreader.h"
|
||||
#include "../io/binarywriter.h"
|
||||
#include "../io/bitreader.h"
|
||||
#include "../io/catchiofailure.h"
|
||||
#include "../io/copy.h"
|
||||
#include "../io/inifile.h"
|
||||
#include "../io/misc.h"
|
||||
|
@ -44,9 +43,6 @@ using namespace CPPUNIT_NS;
|
|||
*/
|
||||
class IoTests : public TestFixture {
|
||||
CPPUNIT_TEST_SUITE(IoTests);
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
CPPUNIT_TEST(testFailure);
|
||||
#endif
|
||||
CPPUNIT_TEST(testBinaryReader);
|
||||
CPPUNIT_TEST(testBinaryWriter);
|
||||
CPPUNIT_TEST(testBitReader);
|
||||
|
@ -64,9 +60,6 @@ public:
|
|||
void setUp();
|
||||
void tearDown();
|
||||
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
void testFailure();
|
||||
#endif
|
||||
void testBinaryReader();
|
||||
void testBinaryWriter();
|
||||
void testBitReader();
|
||||
|
@ -90,34 +83,6 @@ void IoTests::tearDown()
|
|||
{
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
/*!
|
||||
* \brief Tests workaround for GCC Bug 66145.
|
||||
* \sa https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145
|
||||
* \remarks
|
||||
* For some reason this unit test doesn't pass under Windows (using GCC 8.2.0). However, when testing
|
||||
* statically linked binaries manually, it works. So ignore it for now since the workaround will be
|
||||
* removed in v5 anyways.
|
||||
*/
|
||||
void IoTests::testFailure()
|
||||
{
|
||||
// check whether workaround works
|
||||
try {
|
||||
fstream stream;
|
||||
stream.exceptions(ios_base::failbit | ios_base::badbit);
|
||||
stream.open("path/to/file/which/does/not/exist", ios_base::in);
|
||||
} catch (...) {
|
||||
catchIoFailure();
|
||||
}
|
||||
|
||||
// check other relevatn exceptions, too
|
||||
vector<int> testVec;
|
||||
map<string, string> testMap;
|
||||
CPPUNIT_ASSERT_THROW(testVec.at(1), out_of_range);
|
||||
CPPUNIT_ASSERT_THROW(testMap.at("test"), out_of_range);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \brief Tests the most important methods of the BinaryReader.
|
||||
*/
|
||||
|
@ -294,22 +259,9 @@ void IoTests::testBitReader()
|
|||
reader.skipBits(8 + 4);
|
||||
CPPUNIT_ASSERT_EQUAL(4_st, reader.bitsAvailable());
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<byte>(0xA), reader.readBits<byte>(4));
|
||||
try {
|
||||
reader.readBit();
|
||||
CPPUNIT_FAIL("no exception");
|
||||
} catch (...) {
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
catchIoFailure();
|
||||
#endif
|
||||
}
|
||||
try {
|
||||
reader.skipBits(1);
|
||||
CPPUNIT_FAIL("no exception");
|
||||
} catch (...) {
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
catchIoFailure();
|
||||
#endif
|
||||
}
|
||||
CPPUNIT_ASSERT_THROW(reader.readBit(), std::ios_base::failure);
|
||||
CPPUNIT_ASSERT_THROW(reader.skipBits(1), std::ios_base::failure);
|
||||
reader.reset(reinterpret_cast<const char *>(testData), sizeof(testData));
|
||||
CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(8 * sizeof(testData)), reader.bitsAvailable());
|
||||
}
|
||||
|
@ -433,15 +385,7 @@ void IoTests::testReadFile()
|
|||
readFile(iniFilePath));
|
||||
|
||||
// fail by exceeding max size
|
||||
try {
|
||||
readFile(iniFilePath, 10);
|
||||
cout << "no exception" << endl;
|
||||
CPPUNIT_FAIL("no exception");
|
||||
} catch (...) {
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
catchIoFailure();
|
||||
#endif
|
||||
}
|
||||
CPPUNIT_ASSERT_THROW(readFile(iniFilePath, 10), std::ios_base::failure);
|
||||
|
||||
// handle UTF-8 in path and file contents correctly via NativeFileStream
|
||||
#if !defined(PLATFORM_WINDOWS) || defined(CPP_UTILITIES_USE_NATIVE_FILE_BUFFER)
|
||||
|
@ -503,11 +447,11 @@ void IoTests::testNativeFileStream()
|
|||
try {
|
||||
fileStream.open("non existing file", ios_base::in | ios_base::out | ios_base::binary);
|
||||
CPPUNIT_FAIL("expected exception");
|
||||
} catch (...) {
|
||||
} catch (const std::ios_base::failure &failure) {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
//CPPUNIT_ASSERT_EQUAL(string(catchIoFailure()), "CreateFileW failed: iostream error"s);
|
||||
CPPUNIT_ASSERT_EQUAL("CreateFileW failed: iostream error"s, string(failure.what()));
|
||||
#else
|
||||
CPPUNIT_ASSERT_EQUAL(string(catchIoFailure()), "open failed: iostream error"s);
|
||||
CPPUNIT_ASSERT_EQUAL("open failed: iostream error"s, string(failure.what()));
|
||||
#endif
|
||||
}
|
||||
fileStream.clear();
|
||||
|
@ -529,10 +473,10 @@ void IoTests::testNativeFileStream()
|
|||
fileStream.open(-1, ios_base::in | ios_base::out | ios_base::binary);
|
||||
fileStream.get();
|
||||
CPPUNIT_FAIL("expected exception");
|
||||
} catch (...) {
|
||||
} catch (const std::ios_base::failure &failure) {
|
||||
#ifndef PLATFORM_WINDOWS
|
||||
const string msg = catchIoFailure();
|
||||
TESTUTILS_ASSERT_LIKE("expected error message", "(fdopen failed|failed reading: Bad file descriptor): iostream error", msg);
|
||||
TESTUTILS_ASSERT_LIKE(
|
||||
"expected error message", "(fdopen failed|failed reading: Bad file descriptor): iostream error"s, string(failure.what()));
|
||||
#endif
|
||||
}
|
||||
fileStream.clear();
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "../conversion/stringbuilder.h"
|
||||
#include "../conversion/stringconversion.h"
|
||||
#include "../io/ansiescapecodes.h"
|
||||
#include "../io/catchiofailure.h"
|
||||
#include "../io/misc.h"
|
||||
#include "../io/nativefilestream.h"
|
||||
#include "../io/path.h"
|
||||
|
@ -600,10 +599,9 @@ string TestApplication::readTestfilePathFromSrcRef()
|
|||
#endif // PLATFORM_UNIX
|
||||
|
||||
return srcDirContent += "/testfiles/";
|
||||
} catch (...) {
|
||||
} catch (const std::ios_base::failure &) {
|
||||
cerr << Phrases::Warning << "The file \"srcdirref\" can not be opened. It likely just doesn't exist in the working directory."
|
||||
<< Phrases::EndFlush;
|
||||
catchIoFailure();
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue