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