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. From-SVN: r262456
This commit is contained in:
parent
1c1d2d8ca7
commit
d04dbb8ad3
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user