diff options
Diffstat (limited to 'test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp')
-rw-r--r-- | test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp index 06dd1bb055..a4dffda1f9 100644 --- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp +++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -fcxx-exceptions %s // An explicitly-defaulted function may be declared constexpr only if it would // have been implicitly declared as constexpr. @@ -54,3 +54,61 @@ struct S5 { }; constexpr S5::S5() = default; static_assert(S5().m == 4, ""); + + +// An explicitly-defaulted function may have an exception specification only if +// it is compatible with the exception specification on an implicit declaration. +struct E1 { + E1() noexcept = default; + E1(const E1&) noexcept = default; + E1(E1&&) noexcept = default; + E1 &operator=(const E1&) noexcept = default; + E1 &operator=(E1&&) noexcept = default; + ~E1() noexcept = default; +}; +struct E2 { + E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}} + E2(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy constructor does not match the calculated one}} + E2(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move constructor does not match the calculated one}} + E2 &operator=(const E2&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted copy assignment operator does not match the calculated one}} + E2 &operator=(E2&&) noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted move assignment operator does not match the calculated one}} + ~E2() noexcept(false) = default; // expected-error {{exception specification of explicitly defaulted destructor does not match the calculated one}} +}; + +// If a function is explicitly defaulted on its first declaration +// -- it is implicitly considered to have the same exception-specification as +// if it had been implicitly declared +struct E3 { + E3() = default; + E3(const E3&) = default; + E3(E3&&) = default; + E3 &operator=(const E3&) = default; + E3 &operator=(E3&&) = default; + ~E3() = default; +}; +E3 e3; +static_assert(noexcept(E3(), E3(E3()), E3(e3), e3 = E3(), e3 = e3), ""); +struct E4 { + E4() noexcept(false); + E4(const E4&) noexcept(false); + E4(E4&&) noexcept(false); + E4 &operator=(const E4&) noexcept(false); + E4 &operator=(E4&&) noexcept(false); + ~E4() noexcept(false); +}; +struct E5 { + E5() = default; + E5(const E5&) = default; + E5(E5&&) = default; + E5 &operator=(const E5&) = default; + E5 &operator=(E5&&) = default; + ~E5() = default; + + E4 e4; +}; +E5 e5; +static_assert(!noexcept(E5()), ""); +static_assert(!noexcept(E5(static_cast<E5&&>(e5))), ""); +static_assert(!noexcept(E5(e5)), ""); +static_assert(!noexcept(e5 = E5()), ""); +static_assert(!noexcept(e5 = e5), ""); |