19b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify -std=c++11 %s
29b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct A { };
39b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct B { };
49b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct C { };
59b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
69b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Destructor
79b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct X0 {
89b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}}
99b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com};
109b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct X1 {
119b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}}
129b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com};
139b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}}
149b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
159b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// Copy-assignment operator.
169b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct CA0 {
179b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  CA0 &operator=(const CA0&) throw(A);
189b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com};
199b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct CA1 {
209b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  CA1 &operator=(const CA1&) throw(B);
219b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com};
229b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct CA2 : CA0, CA1 { };
239b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
249b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comvoid test_CA() {
259b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=;
269b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=;
279b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
289b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
299b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
309b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
319b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// In-class member initializers.
329b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct IC0 {
339b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  int inClassInit = 0;
349b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com};
359b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstruct IC1 {
369b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  int inClassInit = (throw B(), 0);
379b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com};
389b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// FIXME: the exception specification on the default constructor is wrong:
399b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com// we cannot currently compute the set of thrown types.
409b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstatic_assert(noexcept(IC0()), "IC0() does not throw");
419b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comstatic_assert(!noexcept(IC1()), "IC1() throws");
429b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
439b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comnamespace PR13381 {
449b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct NoThrowMove {
459b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    NoThrowMove(const NoThrowMove &);
469b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    NoThrowMove(NoThrowMove &&) noexcept;
479b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    NoThrowMove &operator=(const NoThrowMove &) const;
489b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    NoThrowMove &operator=(NoThrowMove &&) const noexcept;
499b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
509b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct NoThrowMoveOnly {
519b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    NoThrowMoveOnly(NoThrowMoveOnly &&) noexcept;
529b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    NoThrowMoveOnly &operator=(NoThrowMoveOnly &&) noexcept;
539b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
549b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct X {
559b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    const NoThrowMove a;
569b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    NoThrowMoveOnly b;
579b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
589b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    static X val();
599b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    static X &ref();
609b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
619b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // These both perform a move, but that copy might throw, because it calls
629b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // NoThrowMove's copy constructor (because PR13381::a is const).
639b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  static_assert(!noexcept(X(X::val())), "");
649b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  static_assert(!noexcept(X::ref() = X::val()), "");
659b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
669b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
679b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comnamespace PR14141 {
689b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // Part of DR1351: the implicit exception-specification is noexcept(false) if
699b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // the set of potential exceptions of the special member function contains
709b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  // "any". Hence it is compatible with noexcept(false).
719b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct ThrowingBase {
729b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ThrowingBase() noexcept(false);
739b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ThrowingBase(const ThrowingBase&) noexcept(false);
749b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ThrowingBase(ThrowingBase&&) noexcept(false);
759b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ThrowingBase &operator=(const ThrowingBase&) noexcept(false);
769b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ThrowingBase &operator=(ThrowingBase&&) noexcept(false);
779b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ~ThrowingBase() noexcept(false);
789b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
799b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Derived : ThrowingBase {
809b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived() noexcept(false) = default;
819b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived(const Derived&) noexcept(false) = default;
829b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived(Derived&&) noexcept(false) = default;
839b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived &operator=(const Derived&) noexcept(false) = default;
849b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived &operator=(Derived&&) noexcept(false) = default;
859b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ~Derived() noexcept(false) = default;
869b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
879b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Derived2 : ThrowingBase {
889b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived2() = default;
899b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived2(const Derived2&) = default;
909b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived2(Derived2&&) = default;
919b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived2 &operator=(const Derived2&) = default;
929b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived2 &operator=(Derived2&&) = default;
939b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ~Derived2() = default;
949b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
959b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Derived3 : ThrowingBase {
969b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
979b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived3(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
989b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived3(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
999b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived3 &operator=(const Derived3&) noexcept(true) = default; // expected-error {{does not match the calculated}}
1009b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Derived3 &operator=(Derived3&&) noexcept(true) = default; // expected-error {{does not match the calculated}}
1019b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    ~Derived3() noexcept(true) = default; // expected-error {{does not match the calculated}}
1029b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
1039b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1049b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1059b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comnamespace rdar13017229 {
1069b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Base {
1079b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    virtual ~Base() {}
1089b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
1099b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1109b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Derived : Base {
1119b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    virtual ~Derived();
1129b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Typo foo(); // expected-error{{unknown type name 'Typo'}}
1139b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
1149b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1159b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com
1169b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.comnamespace InhCtor {
1179b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  template<int> struct X {};
1189b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Base {
1199b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Base(X<0>) noexcept(true);
1209b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Base(X<1>) noexcept(false);
1219b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Base(X<2>) throw(X<2>);
1229b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    template<typename T> Base(T) throw(T);
1239b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
1249b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  template<typename T> struct Throw {
1259b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Throw() throw(T);
1269b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
1279b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Derived : Base, Throw<X<3>> {
1289b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    using Base::Base;
1299b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    Throw<X<4>> x;
1309b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
1319b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  struct Test {
1329b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    friend Derived::Derived(X<0>) throw(X<3>, X<4>);
1339b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    friend Derived::Derived(X<1>) noexcept(false);
1349b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com    friend Derived::Derived(X<2>) throw(X<2>, X<3>, X<4>);
1359b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  };
1369b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com  static_assert(!noexcept(Derived{X<5>{}}), "");
1379b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com}
1389b80e34391ebd835244aea31bd2fb427e209fa0fphilip.liard@gmail.com