aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-05-06 05:04:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-05-06 05:04:56 +0000
commit1b26ab1b5287ec6c00e8e506657abe438c90a71b (patch)
tree0107e12f1ee8eb08535b4042b4e90491a4b4aa3a /test
parent71019a8e1da335af8c2a5d03cb268dd7b19b73a6 (diff)
P1286R2: Remove restriction that the exception specification of a
defaulted special member matches the implicit exception specification. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360011 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp27
-rw-r--r--test/CXX/drs/dr17xx.cpp15
-rw-r--r--test/CXX/except/except.spec/p14.cpp29
-rw-r--r--test/SemaCXX/cxx0x-defaulted-functions.cpp23
-rw-r--r--test/SemaCXX/member-init.cpp2
-rw-r--r--test/SemaTemplate/exception-spec-crash.cpp6
6 files changed, 76 insertions, 26 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 c2f3b5a045..2b7886d383 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
@@ -56,8 +56,8 @@ 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.
+// An explicitly-defaulted function may have a different exception specification
+// from the exception specification on an implicit declaration.
struct E1 {
E1() noexcept = default;
E1(const E1&) noexcept = default;
@@ -67,13 +67,24 @@ struct E1 {
~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}}
+ E2() noexcept(false) = default;
+ E2(const E2&) noexcept(false) = default;
+ E2(E2&&) noexcept(false) = default;
+ E2 &operator=(const E2&) noexcept(false) = default;
+ E2 &operator=(E2&&) noexcept(false) = default;
+ ~E2() noexcept(false) = default;
};
+E2 e2;
+E2 make_e2() noexcept;
+void take_e2(E2&&) noexcept;
+static_assert(!noexcept(E2()), "");
+static_assert(!noexcept(E2(e2)), "");
+static_assert(!noexcept(E2(static_cast<E2&&>(e2))), "");
+static_assert(!noexcept(e2 = e2), "");
+static_assert(!noexcept(e2 = static_cast<E2&&>(e2)), "");
+// FIXME: This expression results in destruction of an E2 temporary; the
+// noexcept expression should evaluate to false.
+static_assert(noexcept(take_e2(make_e2())), "");
// If a function is explicitly defaulted on its first declaration
// -- it is implicitly considered to have the same exception-specification as
diff --git a/test/CXX/drs/dr17xx.cpp b/test/CXX/drs/dr17xx.cpp
index bf7458ea81..ca55c42977 100644
--- a/test/CXX/drs/dr17xx.cpp
+++ b/test/CXX/drs/dr17xx.cpp
@@ -88,3 +88,18 @@ void f() {
}
#endif
} // namespace dr1722
+
+namespace dr1778 { // dr1778: 9
+ // Superseded by P1286R2.
+#if __cplusplus >= 201103L
+ struct A { A() noexcept(true) = default; };
+ struct B { B() noexcept(false) = default; };
+ static_assert(noexcept(A()), "");
+ static_assert(!noexcept(B()), "");
+
+ struct C { A a; C() noexcept(false) = default; };
+ struct D { B b; D() noexcept(true) = default; };
+ static_assert(!noexcept(C()), "");
+ static_assert(noexcept(D()), "");
+#endif
+}
diff --git a/test/CXX/except/except.spec/p14.cpp b/test/CXX/except/except.spec/p14.cpp
index c717d97797..b1c8b207b4 100644
--- a/test/CXX/except/except.spec/p14.cpp
+++ b/test/CXX/except/except.spec/p14.cpp
@@ -83,7 +83,12 @@ namespace PR14141 {
Derived &operator=(const Derived&) noexcept(false) = default;
Derived &operator=(Derived&&) noexcept(false) = default;
~Derived() noexcept(false) = default;
- };
+ } d1;
+ static_assert(!noexcept(Derived()), "");
+ static_assert(!noexcept(Derived(static_cast<Derived&&>(d1))), "");
+ static_assert(!noexcept(Derived(d1)), "");
+ static_assert(!noexcept(d1 = static_cast<Derived&&>(d1)), "");
+ static_assert(!noexcept(d1 = d1), "");
struct Derived2 : ThrowingBase {
Derived2() = default;
Derived2(const Derived2&) = default;
@@ -91,15 +96,21 @@ namespace PR14141 {
Derived2 &operator=(const Derived2&) = default;
Derived2 &operator=(Derived2&&) = default;
~Derived2() = default;
- };
+ } d2;
+ static_assert(!noexcept(Derived2()), "");
+ static_assert(!noexcept(Derived2(static_cast<Derived2&&>(d2))), "");
+ static_assert(!noexcept(Derived2(d2)), "");
+ static_assert(!noexcept(d2 = static_cast<Derived2&&>(d2)), "");
+ static_assert(!noexcept(d2 = d2), "");
struct Derived3 : ThrowingBase {
- Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3 &operator=(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- Derived3 &operator=(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
- ~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
- };
+ Derived3() noexcept(true) = default;
+ Derived3(const Derived3&) noexcept(true) = default;
+ Derived3(Derived3&&) noexcept(true) = default;
+ Derived3 &operator=(const Derived3&) noexcept(true) = default;
+ Derived3 &operator=(Derived3&&) noexcept(true) = default;
+ ~Derived3() noexcept(true) = default;
+ } d3;
+ static_assert(noexcept(Derived3(), Derived3(Derived3()), Derived3(d3), d3 = Derived3(), d3 = d3), "");
}
namespace rdar13017229 {
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 6346e1c235..45a65440d5 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -189,11 +189,11 @@ namespace PR15597 {
~A() noexcept(true) = default;
};
template<typename T> struct B {
- B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
- ~B() noexcept(false) = default; // expected-error {{does not match the calculated one}}
+ B() noexcept(false) = default;
+ ~B() noexcept(false) = default;
};
A<int> a;
- B<int> b; // expected-note {{here}}
+ B<int> b;
}
namespace PR27941 {
@@ -242,3 +242,20 @@ template <typename Type>
E<Type>::E(const int&) {} // expected-error {{definition of explicitly defaulted function}}
}
+
+namespace P1286R2 {
+ struct X {
+ X();
+ };
+ struct A {
+ struct B {
+ B() noexcept(A::value) = default;
+ X x;
+ };
+ decltype(B()) b;
+ static constexpr bool value = true;
+ };
+ A::B b;
+
+ static_assert(noexcept(A::B()), "");
+}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 2c4659afa3..3fcee50e63 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -51,7 +51,7 @@ struct CheckExcSpec {
int n = 0;
};
struct CheckExcSpecFail {
- CheckExcSpecFail() noexcept(true) = default; // expected-error {{exception specification of explicitly defaulted default constructor does not match the calculated one}}
+ CheckExcSpecFail() noexcept(true) = default; // ok, but calls terminate() on exception
ThrowCtor tc = 123;
};
diff --git a/test/SemaTemplate/exception-spec-crash.cpp b/test/SemaTemplate/exception-spec-crash.cpp
index ebbb30a2c2..1418ba65e1 100644
--- a/test/SemaTemplate/exception-spec-crash.cpp
+++ b/test/SemaTemplate/exception-spec-crash.cpp
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -Wno-defaulted-function-deleted
// RUN: %clang_cc1 -std=c++11 -fcxx-exceptions -DCXX_EXCEPTIONS -fsyntax-only -verify %s -Wno-defaulted-function-deleted
+// expected-no-diagnostics
template <class _Tp> struct is_nothrow_move_constructible {
static const bool value = false;
@@ -20,11 +21,6 @@ class basic_string {
class Foo {
Foo(Foo &&) noexcept = default;
-#ifdef CXX_EXCEPTIONS
-// expected-error@-2 {{does not match the calculated}}
-#else
-// expected-no-diagnostics
-#endif
Foo &operator=(Foo &&) noexcept = default;
basic_string<allocator<char> > vectorFoo_;
};