diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-05-15 04:39:51 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-05-15 04:39:51 +0000 |
commit | 3003e1d6626d07e8fc4af95fad95b3a5d4c4af98 (patch) | |
tree | 34551eee521a8c701bfc32261f462ca62ca85750 /test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp | |
parent | 4b50263096457552ee86eb790c9638c6bb7357fa (diff) |
Fold the six functions checking explicitly-defaulted special member functions
into one. These were all performing almost identical checks, with different bugs
in each of them.
This fixes PR12806 (we weren't setting the exception specification for an
explicitly-defaulted, non-user-provided default constructor) and enforces
8.4.2/2's rule that an in-class defaulted member must exactly match the implicit
parameter type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156802 91177308-0d34-0410-b5e6-96231b3b80d8
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), ""); |