diff options
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r-- | libstdc++-v3/src/c++11/Makefile.am | 20 | ||||
-rw-r--r-- | libstdc++-v3/src/c++11/Makefile.in | 18 | ||||
-rw-r--r-- | libstdc++-v3/src/c++11/cxx11-ios_failure.cc | 70 | ||||
-rw-r--r-- | libstdc++-v3/src/c++11/ios.cc | 16 | ||||
-rw-r--r-- | libstdc++-v3/src/c++98/ios_failure.cc | 47 | ||||
-rw-r--r-- | libstdc++-v3/src/filesystem/ops.cc | 11 |
6 files changed, 160 insertions, 22 deletions
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am index cf73d4d5c4c..776a4ba36e3 100644 --- a/libstdc++-v3/src/c++11/Makefile.am +++ b/libstdc++-v3/src/c++11/Makefile.am @@ -126,6 +126,26 @@ hashtable_c++0x.lo: hashtable_c++0x.cc hashtable_c++0x.o: hashtable_c++0x.cc $(CXXCOMPILE) -fimplicit-templates -c $< +if ENABLE_DUAL_ABI +# Rewrite the type info for __ios_failure. +rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt13__ios_failure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/' + +cxx11-ios_failure-lt.s: cxx11-ios_failure.cc + $(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s + -test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s + $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ + -rm -f tmp-$@ +cxx11-ios_failure.s: cxx11-ios_failure.cc + $(CXXCOMPILE) -S $< -o tmp-$@ + $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ + -rm -f tmp-$@ + +cxx11-ios_failure.lo: cxx11-ios_failure-lt.s + $(LTCXXCOMPILE) -g0 -c $< -o $@ +cxx11-ios_failure.o: cxx11-ios_failure.s + $(CXXCOMPILE) -g0 -c $< +endif + # AM_CXXFLAGS needs to be in each subdirectory so that it can be # modified in a per-library or per-sub-library way. Need to manually # set this option because CONFIG_CXXFLAGS has to be after diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in index 295d915b436..6d78fd81f50 100644 --- a/libstdc++-v3/src/c++11/Makefile.in +++ b/libstdc++-v3/src/c++11/Makefile.in @@ -433,6 +433,9 @@ sources = \ libc__11convenience_la_SOURCES = $(sources) $(inst_sources) +# Rewrite the type info for __ios_failure. +@ENABLE_DUAL_ABI_TRUE@rewrite_ios_failure_typeinfo = sed -e '/^_*_ZTISt13__ios_failure:/,/_ZTVN10__cxxabiv120__si_class_type_infoE/s/_ZTVN10__cxxabiv120__si_class_type_infoE/_ZTVSt19__iosfail_type_info/' + # AM_CXXFLAGS needs to be in each subdirectory so that it can be # modified in a per-library or per-sub-library way. Need to manually # set this option because CONFIG_CXXFLAGS has to be after @@ -748,6 +751,21 @@ hashtable_c++0x.lo: hashtable_c++0x.cc hashtable_c++0x.o: hashtable_c++0x.cc $(CXXCOMPILE) -fimplicit-templates -c $< +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure-lt.s: cxx11-ios_failure.cc +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -S $< -o tmp-cxx11-ios_failure-lt.s +@ENABLE_DUAL_ABI_TRUE@ -test -f tmp-cxx11-ios_failure-lt.o && mv -f tmp-cxx11-ios_failure-lt.o tmp-cxx11-ios_failure-lt.s +@ENABLE_DUAL_ABI_TRUE@ $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ +@ENABLE_DUAL_ABI_TRUE@ -rm -f tmp-$@ +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.s: cxx11-ios_failure.cc +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) -S $< -o tmp-$@ +@ENABLE_DUAL_ABI_TRUE@ $(rewrite_ios_failure_typeinfo) tmp-$@ > $@ +@ENABLE_DUAL_ABI_TRUE@ -rm -f tmp-$@ + +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.lo: cxx11-ios_failure-lt.s +@ENABLE_DUAL_ABI_TRUE@ $(LTCXXCOMPILE) -g0 -c $< -o $@ +@ENABLE_DUAL_ABI_TRUE@cxx11-ios_failure.o: cxx11-ios_failure.s +@ENABLE_DUAL_ABI_TRUE@ $(CXXCOMPILE) -g0 -c $< + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc index 2f60408782e..8833ba8c91a 100644 --- a/libstdc++-v3/src/c++11/cxx11-ios_failure.cc +++ b/libstdc++-v3/src/c++11/cxx11-ios_failure.cc @@ -28,6 +28,15 @@ #define _GLIBCXX_USE_CXX11_ABI 1 #include <ios> +#include <bits/functexcept.h> +#include <cxxabi.h> + +#ifdef _GLIBCXX_USE_NLS +# include <libintl.h> +# define _(msgid) gettext (msgid) +#else +# define _(msgid) (msgid) +#endif #if ! _GLIBCXX_USE_DUAL_ABI # error This file should not be compiled for this configuration. @@ -91,5 +100,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ios_base::failure::what() const throw() { return runtime_error::what(); } +#if __cpp_rtti + // These functions are defined in src/c++98/ios_failure.cc + extern void __construct_ios_failure(void*, const char*); + extern void __destroy_ios_failure(void*); + extern bool __is_ios_failure_handler(const __cxxabiv1::__class_type_info*); + + // The type thrown to report errors during stream buffer operations. + // In addition to the ios::failure[abi:cxx11] base class it also has a + // member of the gcc4-compatible ios::failure type (in an opaque buffer). + struct __ios_failure : std::ios::failure + { + __ios_failure(const char* s) : failure(s) + { __construct_ios_failure(buf, runtime_error::what()); } + + ~__ios_failure() + { __destroy_ios_failure(buf); } + + // Use std::runtime_error as a proxy for the gcc4-compatible ios::failure + // (which can't be declared here because _GLIBCXX_USE_CXX11_ABI == 1). + // There are assertions in src/c++98/ios_failure.cc to ensure the size + // and alignment assumptions are valid. + alignas(runtime_error) unsigned char buf[sizeof(runtime_error)]; + }; + + // Custom type info for __ios_failure. + class __iosfail_type_info : __cxxabiv1::__si_class_type_info + { + ~__iosfail_type_info(); + + bool + __do_upcast (const __class_type_info *dst_type, + void **obj_ptr) const override; + }; + + __iosfail_type_info::~__iosfail_type_info() = default; + + // This function gets called to see if an exception of type + // __ios_failure can be upcast to the type in a catch handler. + bool + __iosfail_type_info::__do_upcast(const __class_type_info *dst_type, + void **obj_ptr) const + { + // If the handler is for the gcc4-compatible ios::failure type then + // catch the object stored in __ios_failure::buf instead of + // the __ios_failure exception object itself. + if (__is_ios_failure_handler(dst_type)) + { + *obj_ptr = static_cast<__ios_failure*>(*obj_ptr)->buf; + return true; + } + // Otherwise proceed as normal to see if the handler matches. + return __class_type_info::__do_upcast(dst_type, obj_ptr); + } +#else // ! __cpp_rtti + using __ios_failure = ios::failure; +#endif + + void + __throw_ios_failure(const char* __s __attribute__((unused))) + { _GLIBCXX_THROW_OR_ABORT(__ios_failure(_(__s))); } + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++11/ios.cc b/libstdc++-v3/src/c++11/ios.cc index 9061989f806..ef0da960007 100644 --- a/libstdc++-v3/src/c++11/ios.cc +++ b/libstdc++-v3/src/c++11/ios.cc @@ -26,29 +26,13 @@ // ISO C++ 14882: 27.4 Iostreams base classes // -// Determines the version of ios_base::failure thrown by __throw_ios_failure. -// If !_GLIBCXX_USE_DUAL_ABI this will get undefined automatically. -#define _GLIBCXX_USE_CXX11_ABI 1 - #include <ios> #include <limits> -#include <bits/functexcept.h> - -#ifdef _GLIBCXX_USE_NLS -# include <libintl.h> -# define _(msgid) gettext (msgid) -#else -# define _(msgid) (msgid) -#endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - void - __throw_ios_failure(const char* __s __attribute__((unused))) - { _GLIBCXX_THROW_OR_ABORT(ios_base::failure(_(__s))); } - // Definitions for static const members of ios_base. const ios_base::fmtflags ios_base::boolalpha; const ios_base::fmtflags ios_base::dec; diff --git a/libstdc++-v3/src/c++98/ios_failure.cc b/libstdc++-v3/src/c++98/ios_failure.cc index 3ba25f81279..e7f35e21e2c 100644 --- a/libstdc++-v3/src/c++98/ios_failure.cc +++ b/libstdc++-v3/src/c++98/ios_failure.cc @@ -29,6 +29,18 @@ #define _GLIBCXX_USE_CXX11_ABI 0 #include <ios> +#if _GLIBCXX_USE_DUAL_ABI && __cpp_rtti +#include <cxxabi.h> +#include <typeinfo> +#endif + +#ifdef _GLIBCXX_USE_NLS +# include <libintl.h> +# define _(msgid) gettext (msgid) +#else +# define _(msgid) (msgid) +#endif + namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION @@ -43,5 +55,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ios_base::failure::what() const throw() { return _M_msg.c_str(); } +#if _GLIBCXX_USE_DUAL_ABI + // When the dual ABI is enabled __throw_ios_failure() is defined in + // src/c++11/cxx11-ios_failure.cc +#if __cpp_rtti + // If RTTI is enabled the exception type thrown will use these functions to + // construct/destroy a gcc4-compatible ios::failure object in a buffer, + // and to catch that object via a handler of the gcc4-compatible type. + void + __construct_ios_failure(void* buf, const char* msg) + { ::new(buf) ios_base::failure(msg); } + + void + __destroy_ios_failure(void* buf) + { static_cast<ios_base::failure*>(buf)->~failure(); } + + bool + __is_ios_failure_handler(const __cxxabiv1::__class_type_info* type) + { return *type == typeid(ios::failure); } + + namespace { + // C++98-style static assertions to ensure ios::failure fits in a buffer + // with the same size and alignment as runtime_error: + typedef char S[1 / (sizeof(ios::failure) <= sizeof(runtime_error))]; + typedef char A[1 / (__alignof(ios::failure) <= __alignof(runtime_error))]; + } +#endif // __cpp_rtti + +#else // ! _GLIBCXX_USE_DUAL_ABI + + void + __throw_ios_failure(const char* __s __attribute__((unused))) + { _GLIBCXX_THROW_OR_ABORT(ios::failure(_(__s))); } + +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index 8de3511346e..397a8d7ffe7 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -720,10 +720,8 @@ namespace if (::mkdir(p.c_str(), mode)) { const int err = errno; - if (err != EEXIST || !is_directory(p)) + if (err != EEXIST || !is_directory(p, ec)) ec.assign(err, std::generic_category()); - else - ec.clear(); } else { @@ -1391,10 +1389,11 @@ fs::space(const path& p, error_code& ec) noexcept ec.assign(errno, std::generic_category()); else { + uintmax_t fragment_size = f.f_frsize; info = space_info{ - f.f_blocks * f.f_frsize, - f.f_bfree * f.f_frsize, - f.f_bavail * f.f_frsize + f.f_blocks * fragment_size, + f.f_bfree * fragment_size, + f.f_bavail * fragment_size }; ec.clear(); } |