aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r--libstdc++-v3/src/c++11/Makefile.am20
-rw-r--r--libstdc++-v3/src/c++11/Makefile.in18
-rw-r--r--libstdc++-v3/src/c++11/cxx11-ios_failure.cc70
-rw-r--r--libstdc++-v3/src/c++11/ios.cc16
-rw-r--r--libstdc++-v3/src/c++98/ios_failure.cc47
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc11
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();
}