aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2018-07-05 21:29:51 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2018-07-05 21:29:51 +0000
commit9190361f448ffd64cf689895eb104ccb0dacb2d9 (patch)
tree3c6d2ba152ada4df1eaf32360d28c94b3d60b014
parent4e9be08f79aa152f01d74ef8a00fb0c960d59786 (diff)
PR libstdc++/85831 define move constructors and operators for exceptions
PR libstdc++/85831 * config/abi/pre/gnu.ver: Export move constructors and move assignment operators for std::logic_error and std::runtime_error. * include/std/stdexcept: Use _GLIBCXX_NOTHROW instead of _GLIBCXX_USE_NOEXCEPT. (logic_error, runtime_error): Declare move constructors and move assignment operators. When not declared already, define copy constructors and copy assignment operators as explicit-defaulted. (domain_error, invalid_argument, length_error, out_of_range) (overflow_error, underflow_error): Define move constructors and move assignment operators as explicitly-defaulted. * libsupc++/exception.h (exception): Likewise. * src/c++11/cow-stdexcept.cc (logic_error, runtime_error): Define move constructors and move assignment operators as defaulted. * testsuite/19_diagnostics/stdexcept.cc: Check that constructors and assignment operators are defined. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@262456 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog17
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver7
-rw-r--r--libstdc++-v3/include/std/stdexcept62
-rw-r--r--libstdc++-v3/libsupc++/exception.h8
-rw-r--r--libstdc++-v3/src/c++11/cow-stdexcept.cc15
-rw-r--r--libstdc++-v3/testsuite/19_diagnostics/stdexcept.cc28
6 files changed, 115 insertions, 22 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 38eb2c5fa06..f78d3043858 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,22 @@
2018-07-05 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/85831
+ * config/abi/pre/gnu.ver: Export move constructors and move
+ assignment operators for std::logic_error and std::runtime_error.
+ * include/std/stdexcept: Use _GLIBCXX_NOTHROW instead of
+ _GLIBCXX_USE_NOEXCEPT.
+ (logic_error, runtime_error): Declare move constructors and move
+ assignment operators. When not declared already, define copy
+ constructors and copy assignment operators as explicit-defaulted.
+ (domain_error, invalid_argument, length_error, out_of_range)
+ (overflow_error, underflow_error): Define move constructors and move
+ assignment operators as explicitly-defaulted.
+ * libsupc++/exception.h (exception): Likewise.
+ * src/c++11/cow-stdexcept.cc (logic_error, runtime_error): Define
+ move constructors and move assignment operators as defaulted.
+ * testsuite/19_diagnostics/stdexcept.cc: Check that constructors and
+ assignment operators are defined.
+
* testsuite/21_strings/basic_string/cons/char/deduction.cc: XFAIL for
COW strings.
* testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc:
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 782b1238742..521cebf1f80 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -2014,6 +2014,13 @@ GLIBCXX_3.4.26 {
# std::basic_string::insert(const_iterator, initializer_list)
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE6insertEN9__gnu_cxx17__normal_iteratorIPK[cw]S4_EESt16initializer_listI[cw]E;
+ # std::logic_error move operations
+ _ZNSt11logic_errorC[12]EOS_;
+ _ZNSt11logic_erroraSEOS_;
+ # std::runtime_error move operations
+ _ZNSt13runtime_errorC[12]EOS_;
+ _ZNSt13runtime_erroraSEOS_;
+
} GLIBCXX_3.4.25;
# Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/include/std/stdexcept b/libstdc++-v3/include/std/stdexcept
index 5267e5692bf..4fcc719f005 100644
--- a/libstdc++-v3/include/std/stdexcept
+++ b/libstdc++-v3/include/std/stdexcept
@@ -55,8 +55,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__cow_string();
__cow_string(const std::string&);
__cow_string(const char*, size_t);
- __cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT;
- __cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT;
+ __cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
+ __cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
~__cow_string();
#if __cplusplus >= 201103L
__cow_string(__cow_string&&) noexcept;
@@ -83,7 +83,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
char _M_bytes[sizeof(__str)];
};
- __sso_string() _GLIBCXX_USE_NOEXCEPT;
+ __sso_string() _GLIBCXX_NOTHROW;
__sso_string(const std::string&);
__sso_string(const char*, size_t);
__sso_string(const __sso_string&);
@@ -122,19 +122,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
explicit
logic_error(const char*) _GLIBCXX_TXN_SAFE;
+
+ logic_error(logic_error&&) noexcept;
+ logic_error& operator=(logic_error&&) noexcept;
#endif
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
- logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
- logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
+ logic_error(const logic_error&) _GLIBCXX_NOTHROW;
+ logic_error& operator=(const logic_error&) _GLIBCXX_NOTHROW;
+#elif __cplusplus >= 201103L
+ logic_error(const logic_error&) = default;
+ logic_error& operator=(const logic_error&) = default;
#endif
- virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+ virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
/** Returns a C-style character string describing the general cause of
* the current error (the same string passed to the ctor). */
virtual const char*
- what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+ what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
# ifdef _GLIBCXX_TM_TS_INTERNAL
friend void*
@@ -152,8 +158,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit domain_error(const char*) _GLIBCXX_TXN_SAFE;
domain_error(const domain_error&) = default;
domain_error& operator=(const domain_error&) = default;
+ domain_error(domain_error&&) = default;
+ domain_error& operator=(domain_error&&) = default;
#endif
- virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT;
+ virtual ~domain_error() _GLIBCXX_NOTHROW;
};
/** Thrown to report invalid arguments to functions. */
@@ -165,8 +173,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE;
invalid_argument(const invalid_argument&) = default;
invalid_argument& operator=(const invalid_argument&) = default;
+ invalid_argument(invalid_argument&&) = default;
+ invalid_argument& operator=(invalid_argument&&) = default;
#endif
- virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT;
+ virtual ~invalid_argument() _GLIBCXX_NOTHROW;
};
/** Thrown when an object is constructed that would exceed its maximum
@@ -179,8 +189,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit length_error(const char*) _GLIBCXX_TXN_SAFE;
length_error(const length_error&) = default;
length_error& operator=(const length_error&) = default;
+ length_error(length_error&&) = default;
+ length_error& operator=(length_error&&) = default;
#endif
- virtual ~length_error() _GLIBCXX_USE_NOEXCEPT;
+ virtual ~length_error() _GLIBCXX_NOTHROW;
};
/** This represents an argument whose value is not within the expected
@@ -193,8 +205,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE;
out_of_range(const out_of_range&) = default;
out_of_range& operator=(const out_of_range&) = default;
+ out_of_range(out_of_range&&) = default;
+ out_of_range& operator=(out_of_range&&) = default;
#endif
- virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT;
+ virtual ~out_of_range() _GLIBCXX_NOTHROW;
};
/** Runtime errors represent problems outside the scope of a program;
@@ -214,19 +228,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
explicit
runtime_error(const char*) _GLIBCXX_TXN_SAFE;
+
+ runtime_error(runtime_error&&) noexcept;
+ runtime_error& operator=(runtime_error&&) noexcept;
#endif
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
- runtime_error(const runtime_error&) _GLIBCXX_USE_NOEXCEPT;
- runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT;
+ runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
+ runtime_error& operator=(const runtime_error&) _GLIBCXX_NOTHROW;
+#elif __cplusplus >= 201103L
+ runtime_error(const runtime_error&) = default;
+ runtime_error& operator=(const runtime_error&) = default;
#endif
- virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+ virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
/** Returns a C-style character string describing the general cause of
* the current error (the same string passed to the ctor). */
virtual const char*
- what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+ what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
# ifdef _GLIBCXX_TM_TS_INTERNAL
friend void*
@@ -243,8 +263,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
range_error(const range_error&) = default;
range_error& operator=(const range_error&) = default;
+ range_error(range_error&&) = default;
+ range_error& operator=(range_error&&) = default;
#endif
- virtual ~range_error() _GLIBCXX_USE_NOEXCEPT;
+ virtual ~range_error() _GLIBCXX_NOTHROW;
};
/** Thrown to indicate arithmetic overflow. */
@@ -256,8 +278,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE;
overflow_error(const overflow_error&) = default;
overflow_error& operator=(const overflow_error&) = default;
+ overflow_error(overflow_error&&) = default;
+ overflow_error& operator=(overflow_error&&) = default;
#endif
- virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT;
+ virtual ~overflow_error() _GLIBCXX_NOTHROW;
};
/** Thrown to indicate arithmetic underflow. */
@@ -269,8 +293,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE;
underflow_error(const underflow_error&) = default;
underflow_error& operator=(const underflow_error&) = default;
+ underflow_error(underflow_error&&) = default;
+ underflow_error& operator=(underflow_error&&) = default;
#endif
- virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT;
+ virtual ~underflow_error() _GLIBCXX_NOTHROW;
};
// @} group exceptions
diff --git a/libstdc++-v3/libsupc++/exception.h b/libstdc++-v3/libsupc++/exception.h
index 1adfe7cbef6..426fba22a57 100644
--- a/libstdc++-v3/libsupc++/exception.h
+++ b/libstdc++-v3/libsupc++/exception.h
@@ -60,17 +60,19 @@ namespace std
class exception
{
public:
- exception() _GLIBCXX_USE_NOEXCEPT { }
- virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+ exception() _GLIBCXX_NOTHROW { }
+ virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
#if __cplusplus >= 201103L
exception(const exception&) = default;
exception& operator=(const exception&) = default;
+ exception(exception&&) = default;
+ exception& operator=(exception&&) = default;
#endif
/** Returns a C-style character string describing the general cause
* of the current error. */
virtual const char*
- what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
+ what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
};
} // namespace std
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index 5ad3d94ae31..a2df7892fd4 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -53,7 +53,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
- // Copy constructors and assignment operators defined using COW std::string
+ // Copy/move constructors and assignment operators defined using COW string.
+ // These operations are noexcept even though copying a COW string is not,
+ // but we know that the string member in an exception has not been "leaked"
+ // so copying is a simple reference count increment.
logic_error::logic_error(const logic_error& e) noexcept
: exception(e), _M_msg(e._M_msg) { }
@@ -61,6 +64,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
logic_error& logic_error::operator=(const logic_error& e) noexcept
{ _M_msg = e._M_msg; return *this; }
+ logic_error::logic_error(logic_error&& e) noexcept = default;
+
+ logic_error&
+ logic_error::operator=(logic_error&& e) noexcept = default;
+
runtime_error::runtime_error(const runtime_error& e) noexcept
: exception(e), _M_msg(e._M_msg) { }
@@ -68,6 +76,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
runtime_error::operator=(const runtime_error& e) noexcept
{ _M_msg = e._M_msg; return *this; }
+ runtime_error::runtime_error(runtime_error&& e) noexcept = default;
+
+ runtime_error&
+ runtime_error::operator=(runtime_error&& e) noexcept = default;
+
// New C++11 constructors:
logic_error::logic_error(const char* __arg)
diff --git a/libstdc++-v3/testsuite/19_diagnostics/stdexcept.cc b/libstdc++-v3/testsuite/19_diagnostics/stdexcept.cc
index 82351118733..87d111dddef 100644
--- a/libstdc++-v3/testsuite/19_diagnostics/stdexcept.cc
+++ b/libstdc++-v3/testsuite/19_diagnostics/stdexcept.cc
@@ -219,9 +219,37 @@ void test02()
}
}
+void test03()
+{
+ std::logic_error le1("");
+ // Copy constructor:
+ std::logic_error le2(le1);
+ // Copy assignment operator:
+ le1 = le2;
+#if __cplusplus >= 201103L
+ // Move constructor:
+ std::logic_error le3 = std::move(le1);
+ // Move assignment operator:
+ le1 = std::move(le3);
+#endif
+
+ std::runtime_error re1("");
+ // Copy constructor:
+ std::runtime_error re2(re1);
+ // Copy assignment operator:
+ re1 = re2;
+#if __cplusplus >= 201103L
+ // Move constructor:
+ std::runtime_error re3 = std::move(re1);
+ // Move assignment operator:
+ re1 = std::move(re3);
+#endif
+}
+
int main(void)
{
test01();
test02();
+ test03();
return 0;
}