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>
|
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
|
* testsuite/21_strings/basic_string/cons/char/deduction.cc: XFAIL for
|
||||||
COW strings.
|
COW strings.
|
||||||
* testsuite/21_strings/basic_string/cons/wchar_t/deduction.cc:
|
* 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)
|
# 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;
|
_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;
|
} GLIBCXX_3.4.25;
|
||||||
|
|
||||||
# Symbols in the support library (libsupc++) have their own tag.
|
# Symbols in the support library (libsupc++) have their own tag.
|
||||||
|
|
|
@ -55,8 +55,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
__cow_string();
|
__cow_string();
|
||||||
__cow_string(const std::string&);
|
__cow_string(const std::string&);
|
||||||
__cow_string(const char*, size_t);
|
__cow_string(const char*, size_t);
|
||||||
__cow_string(const __cow_string&) _GLIBCXX_USE_NOEXCEPT;
|
__cow_string(const __cow_string&) _GLIBCXX_NOTHROW;
|
||||||
__cow_string& operator=(const __cow_string&) _GLIBCXX_USE_NOEXCEPT;
|
__cow_string& operator=(const __cow_string&) _GLIBCXX_NOTHROW;
|
||||||
~__cow_string();
|
~__cow_string();
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
__cow_string(__cow_string&&) noexcept;
|
__cow_string(__cow_string&&) noexcept;
|
||||||
|
@ -83,7 +83,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
char _M_bytes[sizeof(__str)];
|
char _M_bytes[sizeof(__str)];
|
||||||
};
|
};
|
||||||
|
|
||||||
__sso_string() _GLIBCXX_USE_NOEXCEPT;
|
__sso_string() _GLIBCXX_NOTHROW;
|
||||||
__sso_string(const std::string&);
|
__sso_string(const std::string&);
|
||||||
__sso_string(const char*, size_t);
|
__sso_string(const char*, size_t);
|
||||||
__sso_string(const __sso_string&);
|
__sso_string(const __sso_string&);
|
||||||
|
@ -122,19 +122,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
explicit
|
explicit
|
||||||
logic_error(const char*) _GLIBCXX_TXN_SAFE;
|
logic_error(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
|
|
||||||
|
logic_error(logic_error&&) noexcept;
|
||||||
|
logic_error& operator=(logic_error&&) noexcept;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
|
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
|
||||||
logic_error(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
|
logic_error(const logic_error&) _GLIBCXX_NOTHROW;
|
||||||
logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
|
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
|
#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
|
/** Returns a C-style character string describing the general cause of
|
||||||
* the current error (the same string passed to the ctor). */
|
* the current error (the same string passed to the ctor). */
|
||||||
virtual const char*
|
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
|
# ifdef _GLIBCXX_TM_TS_INTERNAL
|
||||||
friend void*
|
friend void*
|
||||||
|
@ -152,8 +158,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
explicit domain_error(const char*) _GLIBCXX_TXN_SAFE;
|
explicit domain_error(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
domain_error(const domain_error&) = default;
|
domain_error(const domain_error&) = default;
|
||||||
domain_error& operator=(const domain_error&) = default;
|
domain_error& operator=(const domain_error&) = default;
|
||||||
|
domain_error(domain_error&&) = default;
|
||||||
|
domain_error& operator=(domain_error&&) = default;
|
||||||
#endif
|
#endif
|
||||||
virtual ~domain_error() _GLIBCXX_USE_NOEXCEPT;
|
virtual ~domain_error() _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Thrown to report invalid arguments to functions. */
|
/** Thrown to report invalid arguments to functions. */
|
||||||
|
@ -165,8 +173,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE;
|
explicit invalid_argument(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
invalid_argument(const invalid_argument&) = default;
|
invalid_argument(const invalid_argument&) = default;
|
||||||
invalid_argument& operator=(const invalid_argument&) = default;
|
invalid_argument& operator=(const invalid_argument&) = default;
|
||||||
|
invalid_argument(invalid_argument&&) = default;
|
||||||
|
invalid_argument& operator=(invalid_argument&&) = default;
|
||||||
#endif
|
#endif
|
||||||
virtual ~invalid_argument() _GLIBCXX_USE_NOEXCEPT;
|
virtual ~invalid_argument() _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Thrown when an object is constructed that would exceed its maximum
|
/** 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;
|
explicit length_error(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
length_error(const length_error&) = default;
|
length_error(const length_error&) = default;
|
||||||
length_error& operator=(const length_error&) = default;
|
length_error& operator=(const length_error&) = default;
|
||||||
|
length_error(length_error&&) = default;
|
||||||
|
length_error& operator=(length_error&&) = default;
|
||||||
#endif
|
#endif
|
||||||
virtual ~length_error() _GLIBCXX_USE_NOEXCEPT;
|
virtual ~length_error() _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** This represents an argument whose value is not within the expected
|
/** 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;
|
explicit out_of_range(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
out_of_range(const out_of_range&) = default;
|
out_of_range(const out_of_range&) = default;
|
||||||
out_of_range& operator=(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
|
#endif
|
||||||
virtual ~out_of_range() _GLIBCXX_USE_NOEXCEPT;
|
virtual ~out_of_range() _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Runtime errors represent problems outside the scope of a program;
|
/** Runtime errors represent problems outside the scope of a program;
|
||||||
|
@ -214,19 +228,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
explicit
|
explicit
|
||||||
runtime_error(const char*) _GLIBCXX_TXN_SAFE;
|
runtime_error(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
|
|
||||||
|
runtime_error(runtime_error&&) noexcept;
|
||||||
|
runtime_error& operator=(runtime_error&&) noexcept;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
|
#if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS
|
||||||
runtime_error(const runtime_error&) _GLIBCXX_USE_NOEXCEPT;
|
runtime_error(const runtime_error&) _GLIBCXX_NOTHROW;
|
||||||
runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT;
|
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
|
#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
|
/** Returns a C-style character string describing the general cause of
|
||||||
* the current error (the same string passed to the ctor). */
|
* the current error (the same string passed to the ctor). */
|
||||||
virtual const char*
|
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
|
# ifdef _GLIBCXX_TM_TS_INTERNAL
|
||||||
friend void*
|
friend void*
|
||||||
|
@ -243,8 +263,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
|
explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
range_error(const range_error&) = default;
|
range_error(const range_error&) = default;
|
||||||
range_error& operator=(const range_error&) = default;
|
range_error& operator=(const range_error&) = default;
|
||||||
|
range_error(range_error&&) = default;
|
||||||
|
range_error& operator=(range_error&&) = default;
|
||||||
#endif
|
#endif
|
||||||
virtual ~range_error() _GLIBCXX_USE_NOEXCEPT;
|
virtual ~range_error() _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Thrown to indicate arithmetic overflow. */
|
/** Thrown to indicate arithmetic overflow. */
|
||||||
|
@ -256,8 +278,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE;
|
explicit overflow_error(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
overflow_error(const overflow_error&) = default;
|
overflow_error(const overflow_error&) = default;
|
||||||
overflow_error& operator=(const overflow_error&) = default;
|
overflow_error& operator=(const overflow_error&) = default;
|
||||||
|
overflow_error(overflow_error&&) = default;
|
||||||
|
overflow_error& operator=(overflow_error&&) = default;
|
||||||
#endif
|
#endif
|
||||||
virtual ~overflow_error() _GLIBCXX_USE_NOEXCEPT;
|
virtual ~overflow_error() _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Thrown to indicate arithmetic underflow. */
|
/** Thrown to indicate arithmetic underflow. */
|
||||||
|
@ -269,8 +293,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE;
|
explicit underflow_error(const char*) _GLIBCXX_TXN_SAFE;
|
||||||
underflow_error(const underflow_error&) = default;
|
underflow_error(const underflow_error&) = default;
|
||||||
underflow_error& operator=(const underflow_error&) = default;
|
underflow_error& operator=(const underflow_error&) = default;
|
||||||
|
underflow_error(underflow_error&&) = default;
|
||||||
|
underflow_error& operator=(underflow_error&&) = default;
|
||||||
#endif
|
#endif
|
||||||
virtual ~underflow_error() _GLIBCXX_USE_NOEXCEPT;
|
virtual ~underflow_error() _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
// @} group exceptions
|
// @} group exceptions
|
||||||
|
|
|
@ -60,17 +60,19 @@ namespace std
|
||||||
class exception
|
class exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
exception() _GLIBCXX_USE_NOEXCEPT { }
|
exception() _GLIBCXX_NOTHROW { }
|
||||||
virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
|
virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
exception(const exception&) = default;
|
exception(const exception&) = default;
|
||||||
exception& operator=(const exception&) = default;
|
exception& operator=(const exception&) = default;
|
||||||
|
exception(exception&&) = default;
|
||||||
|
exception& operator=(exception&&) = default;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** Returns a C-style character string describing the general cause
|
/** Returns a C-style character string describing the general cause
|
||||||
* of the current error. */
|
* of the current error. */
|
||||||
virtual const char*
|
virtual const char*
|
||||||
what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
|
what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
|
@ -53,7 +53,10 @@ namespace std _GLIBCXX_VISIBILITY(default)
|
||||||
{
|
{
|
||||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
_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
|
logic_error::logic_error(const logic_error& e) noexcept
|
||||||
: exception(e), _M_msg(e._M_msg) { }
|
: 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
|
logic_error& logic_error::operator=(const logic_error& e) noexcept
|
||||||
{ _M_msg = e._M_msg; return *this; }
|
{ _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
|
runtime_error::runtime_error(const runtime_error& e) noexcept
|
||||||
: exception(e), _M_msg(e._M_msg) { }
|
: exception(e), _M_msg(e._M_msg) { }
|
||||||
|
|
||||||
|
@ -68,6 +76,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
runtime_error::operator=(const runtime_error& e) noexcept
|
runtime_error::operator=(const runtime_error& e) noexcept
|
||||||
{ _M_msg = e._M_msg; return *this; }
|
{ _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:
|
// New C++11 constructors:
|
||||||
|
|
||||||
logic_error::logic_error(const char* __arg)
|
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)
|
int main(void)
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
test02();
|
test02();
|
||||||
|
test03();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue