1 | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify -std=c++11 %s |
2 | struct A { }; |
3 | struct B { }; |
4 | struct C { }; |
5 | |
6 | // Destructor |
7 | struct X0 { |
8 | virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}} |
9 | }; |
10 | struct X1 { |
11 | virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}} |
12 | }; |
13 | struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}} |
14 | |
15 | // Copy-assignment operator. |
16 | struct CA0 { |
17 | CA0 &operator=(const CA0&) throw(A); |
18 | }; |
19 | struct CA1 { |
20 | CA1 &operator=(const CA1&) throw(B); |
21 | }; |
22 | struct CA2 : CA0, CA1 { }; |
23 | |
24 | void test_CA() { |
25 | CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=; |
26 | CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=; |
27 | CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}} |
28 | CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}} |
29 | } |
30 | |
31 | // In-class member initializers. |
32 | struct IC0 { |
33 | int inClassInit = 0; |
34 | }; |
35 | struct IC1 { |
36 | int inClassInit = (throw B(), 0); |
37 | }; |
38 | // FIXME: the exception specification on the default constructor is wrong: |
39 | // we cannot currently compute the set of thrown types. |
40 | static_assert(noexcept(IC0()), "IC0() does not throw"); |
41 | static_assert(!noexcept(IC1()), "IC1() throws"); |
42 | |
43 | namespace PR13381 { |
44 | struct NoThrowMove { |
45 | NoThrowMove(const NoThrowMove &); |
46 | NoThrowMove(NoThrowMove &&) noexcept; |
47 | NoThrowMove &operator=(const NoThrowMove &) const; |
48 | NoThrowMove &operator=(NoThrowMove &&) const noexcept; |
49 | }; |
50 | struct NoThrowMoveOnly { |
51 | NoThrowMoveOnly(NoThrowMoveOnly &&) noexcept; |
52 | NoThrowMoveOnly &operator=(NoThrowMoveOnly &&) noexcept; |
53 | }; |
54 | struct X { |
55 | const NoThrowMove a; |
56 | NoThrowMoveOnly b; |
57 | |
58 | static X val(); |
59 | static X &ref(); |
60 | }; |
61 | // These both perform a move, but that copy might throw, because it calls |
62 | // NoThrowMove's copy constructor (because PR13381::a is const). |
63 | static_assert(!noexcept(X(X::val())), ""); |
64 | static_assert(!noexcept(X::ref() = X::val()), ""); |
65 | } |
66 | |
67 | namespace PR14141 { |
68 | // Part of DR1351: the implicit exception-specification is noexcept(false) if |
69 | // the set of potential exceptions of the special member function contains |
70 | // "any". Hence it is compatible with noexcept(false). |
71 | struct ThrowingBase { |
72 | ThrowingBase() noexcept(false); |
73 | ThrowingBase(const ThrowingBase&) noexcept(false); |
74 | ThrowingBase(ThrowingBase&&) noexcept(false); |
75 | ThrowingBase &operator=(const ThrowingBase&) noexcept(false); |
76 | ThrowingBase &operator=(ThrowingBase&&) noexcept(false); |
77 | ~ThrowingBase() noexcept(false); |
78 | }; |
79 | struct Derived : ThrowingBase { |
80 | Derived() noexcept(false) = default; |
81 | Derived(const Derived&) noexcept(false) = default; |
82 | Derived(Derived&&) noexcept(false) = default; |
83 | Derived &operator=(const Derived&) noexcept(false) = default; |
84 | Derived &operator=(Derived&&) noexcept(false) = default; |
85 | ~Derived() noexcept(false) = default; |
86 | }; |
87 | struct Derived2 : ThrowingBase { |
88 | Derived2() = default; |
89 | Derived2(const Derived2&) = default; |
90 | Derived2(Derived2&&) = default; |
91 | Derived2 &operator=(const Derived2&) = default; |
92 | Derived2 &operator=(Derived2&&) = default; |
93 | ~Derived2() = default; |
94 | }; |
95 | struct Derived3 : ThrowingBase { |
96 | Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}} |
97 | Derived3(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}} |
98 | Derived3(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}} |
99 | Derived3 &operator=(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}} |
100 | Derived3 &operator=(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}} |
101 | ~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}} |
102 | }; |
103 | } |
104 | |
105 | namespace rdar13017229 { |
106 | struct Base { |
107 | virtual ~Base() {} |
108 | }; |
109 | |
110 | struct Derived : Base { |
111 | virtual ~Derived(); |
112 | Typo foo(); // expected-error{{unknown type name 'Typo'}} |
113 | }; |
114 | } |
115 | |
116 | namespace InhCtor { |
117 | template<int> struct X {}; |
118 | struct Base { |
119 | Base(X<0>) noexcept(true); |
120 | Base(X<1>) noexcept(false); |
121 | Base(X<2>) throw(X<2>); |
122 | template<typename T> Base(T) throw(T); |
123 | }; |
124 | template<typename T> struct Throw { |
125 | Throw() throw(T); |
126 | }; |
127 | struct Derived1 : Base, X<5> { |
128 | using Base::Base; |
129 | int n; |
130 | }; |
131 | struct Derived2 : Base, Throw<X<3>> { |
132 | using Base::Base; |
133 | }; |
134 | struct Derived3 : Base { |
135 | using Base::Base; |
136 | Throw<X<4>> x; |
137 | }; |
138 | static_assert(noexcept(Derived1(X<0>())), ""); |
139 | static_assert(!noexcept(Derived1(X<1>())), ""); |
140 | static_assert(!noexcept(Derived1(X<2>())), ""); |
141 | static_assert(!noexcept(Derived2(X<0>())), ""); |
142 | static_assert(!noexcept(Derived3(X<0>())), ""); |
143 | } |
144 | |