155 lines · cpp
1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify -std=c++11 %s2struct A { };3struct B { };4struct C { };5 6// Destructor7struct X0 { 8 virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}} 9};10struct X1 { 11 virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}} 12};13struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}}14 15// Copy-assignment operator.16struct CA0 {17 CA0 &operator=(const CA0&) throw(A);18};19struct CA1 {20 CA1 &operator=(const CA1&) throw(B);21};22struct CA2 : CA0, CA1 { };23 24void 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.32struct IC0 {33 int inClassInit = 0;34};35struct 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.40static_assert(noexcept(IC0()), "IC0() does not throw");41static_assert(!noexcept(IC1()), "IC1() throws");42 43namespace 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 calls62 // 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 67namespace PR14141 {68 // Part of DR1351: the implicit exception-specification is noexcept(false) if69 // the set of potential exceptions of the special member function contains70 // "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 } d1;87 static_assert(!noexcept(Derived()), "");88 static_assert(!noexcept(Derived(static_cast<Derived&&>(d1))), "");89 static_assert(!noexcept(Derived(d1)), "");90 static_assert(!noexcept(d1 = static_cast<Derived&&>(d1)), "");91 static_assert(!noexcept(d1 = d1), "");92 struct Derived2 : ThrowingBase {93 Derived2() = default;94 Derived2(const Derived2&) = default;95 Derived2(Derived2&&) = default;96 Derived2 &operator=(const Derived2&) = default;97 Derived2 &operator=(Derived2&&) = default;98 ~Derived2() = default;99 } d2;100 static_assert(!noexcept(Derived2()), "");101 static_assert(!noexcept(Derived2(static_cast<Derived2&&>(d2))), "");102 static_assert(!noexcept(Derived2(d2)), "");103 static_assert(!noexcept(d2 = static_cast<Derived2&&>(d2)), "");104 static_assert(!noexcept(d2 = d2), "");105 struct Derived3 : ThrowingBase {106 Derived3() noexcept(true) = default;107 Derived3(const Derived3&) noexcept(true) = default;108 Derived3(Derived3&&) noexcept(true) = default;109 Derived3 &operator=(const Derived3&) noexcept(true) = default;110 Derived3 &operator=(Derived3&&) noexcept(true) = default;111 ~Derived3() noexcept(true) = default;112 } d3;113 static_assert(noexcept(Derived3(), Derived3(Derived3()), Derived3(d3), d3 = Derived3(), d3 = d3), "");114}115 116namespace rdar13017229 {117 struct Base {118 virtual ~Base() {}119 };120 121 struct Derived : Base {122 virtual ~Derived();123 Typo foo(); // expected-error{{unknown type name 'Typo'}}124 };125}126 127namespace InhCtor {128 template<int> struct X {};129 struct Base {130 Base(X<0>) noexcept(true);131 Base(X<1>) noexcept(false);132 Base(X<2>) throw(X<2>);133 template<typename T> Base(T) throw(T);134 };135 template<typename T> struct Throw {136 Throw() throw(T);137 };138 struct Derived1 : Base, X<5> {139 using Base::Base;140 int n;141 };142 struct Derived2 : Base, Throw<X<3>> {143 using Base::Base;144 };145 struct Derived3 : Base {146 using Base::Base;147 Throw<X<4>> x;148 };149 static_assert(noexcept(Derived1(X<0>())), "");150 static_assert(!noexcept(Derived1(X<1>())), "");151 static_assert(!noexcept(Derived1(X<2>())), "");152 static_assert(!noexcept(Derived2(X<0>())), "");153 static_assert(!noexcept(Derived3(X<0>())), "");154}155