19ca5c425SRichard Smith // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify -std=c++11 %s
22f3d9e82SDouglas Gregor struct A { };
32f3d9e82SDouglas Gregor struct B { };
468e11365SDouglas Gregor struct C { };
52f3d9e82SDouglas Gregor
668e11365SDouglas Gregor // Destructor
72f3d9e82SDouglas Gregor struct X0 {
82f3d9e82SDouglas Gregor virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}}
92f3d9e82SDouglas Gregor };
102f3d9e82SDouglas Gregor struct X1 {
112f3d9e82SDouglas Gregor virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}}
122f3d9e82SDouglas Gregor };
132f3d9e82SDouglas Gregor struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}}
142f3d9e82SDouglas Gregor
1568e11365SDouglas Gregor // Copy-assignment operator.
1668e11365SDouglas Gregor struct CA0 {
1768e11365SDouglas Gregor CA0 &operator=(const CA0&) throw(A);
1868e11365SDouglas Gregor };
1968e11365SDouglas Gregor struct CA1 {
2068e11365SDouglas Gregor CA1 &operator=(const CA1&) throw(B);
2168e11365SDouglas Gregor };
2268e11365SDouglas Gregor struct CA2 : CA0, CA1 { };
2368e11365SDouglas Gregor
test_CA()2468e11365SDouglas Gregor void test_CA() {
2568e11365SDouglas Gregor CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=;
2668e11365SDouglas Gregor CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=;
2768e11365SDouglas Gregor CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
2868e11365SDouglas Gregor CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
2968e11365SDouglas Gregor }
30938f40b5SRichard Smith
31938f40b5SRichard Smith // In-class member initializers.
32938f40b5SRichard Smith struct IC0 {
33938f40b5SRichard Smith int inClassInit = 0;
34938f40b5SRichard Smith };
35938f40b5SRichard Smith struct IC1 {
36938f40b5SRichard Smith int inClassInit = (throw B(), 0);
37938f40b5SRichard Smith };
38938f40b5SRichard Smith // FIXME: the exception specification on the default constructor is wrong:
39938f40b5SRichard Smith // we cannot currently compute the set of thrown types.
40938f40b5SRichard Smith static_assert(noexcept(IC0()), "IC0() does not throw");
41938f40b5SRichard Smith static_assert(!noexcept(IC1()), "IC1() throws");
421c6461efSRichard Smith
431c6461efSRichard Smith namespace PR13381 {
441c6461efSRichard Smith struct NoThrowMove {
451c6461efSRichard Smith NoThrowMove(const NoThrowMove &);
461c6461efSRichard Smith NoThrowMove(NoThrowMove &&) noexcept;
47c91d12ceSRichard Smith NoThrowMove &operator=(const NoThrowMove &) const;
48c91d12ceSRichard Smith NoThrowMove &operator=(NoThrowMove &&) const noexcept;
491c6461efSRichard Smith };
501c6461efSRichard Smith struct NoThrowMoveOnly {
511c6461efSRichard Smith NoThrowMoveOnly(NoThrowMoveOnly &&) noexcept;
521c6461efSRichard Smith NoThrowMoveOnly &operator=(NoThrowMoveOnly &&) noexcept;
531c6461efSRichard Smith };
541c6461efSRichard Smith struct X {
551c6461efSRichard Smith const NoThrowMove a;
561c6461efSRichard Smith NoThrowMoveOnly b;
571c6461efSRichard Smith
581c6461efSRichard Smith static X val();
591c6461efSRichard Smith static X &ref();
601c6461efSRichard Smith };
611c6461efSRichard Smith // These both perform a move, but that copy might throw, because it calls
621c6461efSRichard Smith // NoThrowMove's copy constructor (because PR13381::a is const).
631c6461efSRichard Smith static_assert(!noexcept(X(X::val())), "");
641c6461efSRichard Smith static_assert(!noexcept(X::ref() = X::val()), "");
651c6461efSRichard Smith }
66c25be714SRichard Smith
67c25be714SRichard Smith namespace PR14141 {
68c25be714SRichard Smith // Part of DR1351: the implicit exception-specification is noexcept(false) if
69c25be714SRichard Smith // the set of potential exceptions of the special member function contains
70c25be714SRichard Smith // "any". Hence it is compatible with noexcept(false).
71c25be714SRichard Smith struct ThrowingBase {
72c25be714SRichard Smith ThrowingBase() noexcept(false);
73c25be714SRichard Smith ThrowingBase(const ThrowingBase&) noexcept(false);
74c25be714SRichard Smith ThrowingBase(ThrowingBase&&) noexcept(false);
75c25be714SRichard Smith ThrowingBase &operator=(const ThrowingBase&) noexcept(false);
76c25be714SRichard Smith ThrowingBase &operator=(ThrowingBase&&) noexcept(false);
77c25be714SRichard Smith ~ThrowingBase() noexcept(false);
78c25be714SRichard Smith };
79c25be714SRichard Smith struct Derived : ThrowingBase {
80c25be714SRichard Smith Derived() noexcept(false) = default;
81c25be714SRichard Smith Derived(const Derived&) noexcept(false) = default;
82c25be714SRichard Smith Derived(Derived&&) noexcept(false) = default;
83c25be714SRichard Smith Derived &operator=(const Derived&) noexcept(false) = default;
84c25be714SRichard Smith Derived &operator=(Derived&&) noexcept(false) = default;
85c25be714SRichard Smith ~Derived() noexcept(false) = default;
86*2b45b267SRichard Smith } d1;
87*2b45b267SRichard Smith static_assert(!noexcept(Derived()), "");
88*2b45b267SRichard Smith static_assert(!noexcept(Derived(static_cast<Derived&&>(d1))), "");
89*2b45b267SRichard Smith static_assert(!noexcept(Derived(d1)), "");
90*2b45b267SRichard Smith static_assert(!noexcept(d1 = static_cast<Derived&&>(d1)), "");
91*2b45b267SRichard Smith static_assert(!noexcept(d1 = d1), "");
92c25be714SRichard Smith struct Derived2 : ThrowingBase {
93c25be714SRichard Smith Derived2() = default;
94c25be714SRichard Smith Derived2(const Derived2&) = default;
95c25be714SRichard Smith Derived2(Derived2&&) = default;
96c25be714SRichard Smith Derived2 &operator=(const Derived2&) = default;
97c25be714SRichard Smith Derived2 &operator=(Derived2&&) = default;
98c25be714SRichard Smith ~Derived2() = default;
99*2b45b267SRichard Smith } d2;
100*2b45b267SRichard Smith static_assert(!noexcept(Derived2()), "");
101*2b45b267SRichard Smith static_assert(!noexcept(Derived2(static_cast<Derived2&&>(d2))), "");
102*2b45b267SRichard Smith static_assert(!noexcept(Derived2(d2)), "");
103*2b45b267SRichard Smith static_assert(!noexcept(d2 = static_cast<Derived2&&>(d2)), "");
104*2b45b267SRichard Smith static_assert(!noexcept(d2 = d2), "");
105c25be714SRichard Smith struct Derived3 : ThrowingBase {
106*2b45b267SRichard Smith Derived3() noexcept(true) = default;
107*2b45b267SRichard Smith Derived3(const Derived3&) noexcept(true) = default;
108*2b45b267SRichard Smith Derived3(Derived3&&) noexcept(true) = default;
109*2b45b267SRichard Smith Derived3 &operator=(const Derived3&) noexcept(true) = default;
110*2b45b267SRichard Smith Derived3 &operator=(Derived3&&) noexcept(true) = default;
111*2b45b267SRichard Smith ~Derived3() noexcept(true) = default;
112*2b45b267SRichard Smith } d3;
113*2b45b267SRichard Smith static_assert(noexcept(Derived3(), Derived3(Derived3()), Derived3(d3), d3 = Derived3(), d3 = d3), "");
114c25be714SRichard Smith }
115bc0e5c01SDouglas Gregor
116bc0e5c01SDouglas Gregor namespace rdar13017229 {
117bc0e5c01SDouglas Gregor struct Base {
~Baserdar13017229::Base118bc0e5c01SDouglas Gregor virtual ~Base() {}
119bc0e5c01SDouglas Gregor };
120bc0e5c01SDouglas Gregor
121bc0e5c01SDouglas Gregor struct Derived : Base {
122bc0e5c01SDouglas Gregor virtual ~Derived();
123bc0e5c01SDouglas Gregor Typo foo(); // expected-error{{unknown type name 'Typo'}}
124bc0e5c01SDouglas Gregor };
125bc0e5c01SDouglas Gregor }
126b7151b91SRichard Smith
127b7151b91SRichard Smith namespace InhCtor {
128b7151b91SRichard Smith template<int> struct X {};
129b7151b91SRichard Smith struct Base {
130b7151b91SRichard Smith Base(X<0>) noexcept(true);
131b7151b91SRichard Smith Base(X<1>) noexcept(false);
132b7151b91SRichard Smith Base(X<2>) throw(X<2>);
133b7151b91SRichard Smith template<typename T> Base(T) throw(T);
134b7151b91SRichard Smith };
135b7151b91SRichard Smith template<typename T> struct Throw {
136b7151b91SRichard Smith Throw() throw(T);
137b7151b91SRichard Smith };
1385179eb78SRichard Smith struct Derived1 : Base, X<5> {
1395179eb78SRichard Smith using Base::Base;
1405179eb78SRichard Smith int n;
1415179eb78SRichard Smith };
1425179eb78SRichard Smith struct Derived2 : Base, Throw<X<3>> {
1435179eb78SRichard Smith using Base::Base;
1445179eb78SRichard Smith };
1455179eb78SRichard Smith struct Derived3 : Base {
146b7151b91SRichard Smith using Base::Base;
147b7151b91SRichard Smith Throw<X<4>> x;
148b7151b91SRichard Smith };
1495179eb78SRichard Smith static_assert(noexcept(Derived1(X<0>())), "");
1505179eb78SRichard Smith static_assert(!noexcept(Derived1(X<1>())), "");
1515179eb78SRichard Smith static_assert(!noexcept(Derived1(X<2>())), "");
1525179eb78SRichard Smith static_assert(!noexcept(Derived2(X<0>())), "");
1535179eb78SRichard Smith static_assert(!noexcept(Derived3(X<0>())), "");
154b7151b91SRichard Smith }
155