Remove workaround for GCC Bug 66145

This commit is contained in:
Marius Kittler 2018-10-04 18:07:30 +02:00 committed by Martchus
parent 2f141adb6f
commit 132f936c57
11 changed files with 27 additions and 165 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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();
}
}

View File

@ -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);

View File

@ -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);
}

View File

@ -8,7 +8,6 @@
#include <memory>
#include <streambuf>
#include <string>
#else
#endif
#include <fstream>

View File

@ -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();

View File

@ -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();
}