reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify -std=c++11 %s
struct A { };
struct B { };
struct C { };

// Destructor
struct X0 { 
  virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}} 
};
struct X1 { 
  virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}} 
};
struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}}
 
// Copy-assignment operator.
struct CA0 {
  CA0 &operator=(const CA0&) throw(A);
};
struct CA1 {
  CA1 &operator=(const CA1&) throw(B);
};
struct CA2 : CA0, CA1 { };

void test_CA() {
  CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=;
  CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=;
  CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
  CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
}

// In-class member initializers.
struct IC0 {
  int inClassInit = 0;
};
struct IC1 {
  int inClassInit = (throw B(), 0);
};
// FIXME: the exception specification on the default constructor is wrong:
// we cannot currently compute the set of thrown types.
static_assert(noexcept(IC0()), "IC0() does not throw");
static_assert(!noexcept(IC1()), "IC1() throws");

namespace PR13381 {
  struct NoThrowMove {
    NoThrowMove(const NoThrowMove &);
    NoThrowMove(NoThrowMove &&) noexcept;
    NoThrowMove &operator=(const NoThrowMove &) const;
    NoThrowMove &operator=(NoThrowMove &&) const noexcept;
  };
  struct NoThrowMoveOnly {
    NoThrowMoveOnly(NoThrowMoveOnly &&) noexcept;
    NoThrowMoveOnly &operator=(NoThrowMoveOnly &&) noexcept;
  };
  struct X {
    const NoThrowMove a;
    NoThrowMoveOnly b;

    static X val();
    static X &ref();
  };
  // These both perform a move, but that copy might throw, because it calls
  // NoThrowMove's copy constructor (because PR13381::a is const).
  static_assert(!noexcept(X(X::val())), "");
  static_assert(!noexcept(X::ref() = X::val()), "");
}

namespace PR14141 {
  // Part of DR1351: the implicit exception-specification is noexcept(false) if
  // the set of potential exceptions of the special member function contains
  // "any". Hence it is compatible with noexcept(false).
  struct ThrowingBase {
    ThrowingBase() noexcept(false);
    ThrowingBase(const ThrowingBase&) noexcept(false);
    ThrowingBase(ThrowingBase&&) noexcept(false);
    ThrowingBase &operator=(const ThrowingBase&) noexcept(false);
    ThrowingBase &operator=(ThrowingBase&&) noexcept(false);
    ~ThrowingBase() noexcept(false);
  };
  struct Derived : ThrowingBase {
    Derived() noexcept(false) = default;
    Derived(const Derived&) noexcept(false) = default;
    Derived(Derived&&) noexcept(false) = default;
    Derived &operator=(const Derived&) noexcept(false) = default;
    Derived &operator=(Derived&&) noexcept(false) = default;
    ~Derived() noexcept(false) = default;
  } d1;
  static_assert(!noexcept(Derived()), "");
  static_assert(!noexcept(Derived(static_cast<Derived&&>(d1))), "");
  static_assert(!noexcept(Derived(d1)), "");
  static_assert(!noexcept(d1 = static_cast<Derived&&>(d1)), "");
  static_assert(!noexcept(d1 = d1), "");
  struct Derived2 : ThrowingBase {
    Derived2() = default;
    Derived2(const Derived2&) = default;
    Derived2(Derived2&&) = default;
    Derived2 &operator=(const Derived2&) = default;
    Derived2 &operator=(Derived2&&) = default;
    ~Derived2() = default;
  } d2;
  static_assert(!noexcept(Derived2()), "");
  static_assert(!noexcept(Derived2(static_cast<Derived2&&>(d2))), "");
  static_assert(!noexcept(Derived2(d2)), "");
  static_assert(!noexcept(d2 = static_cast<Derived2&&>(d2)), "");
  static_assert(!noexcept(d2 = d2), "");
  struct Derived3 : ThrowingBase {
    Derived3() noexcept(true) = default;
    Derived3(const Derived3&) noexcept(true) = default;
    Derived3(Derived3&&) noexcept(true) = default;
    Derived3 &operator=(const Derived3&) noexcept(true) = default;
    Derived3 &operator=(Derived3&&) noexcept(true) = default;
    ~Derived3() noexcept(true) = default;
  } d3;
  static_assert(noexcept(Derived3(), Derived3(Derived3()), Derived3(d3), d3 = Derived3(), d3 = d3), "");
}

namespace rdar13017229 {
  struct Base {
    virtual ~Base() {}
  };
  
  struct Derived : Base {
    virtual ~Derived();
    Typo foo(); // expected-error{{unknown type name 'Typo'}}
  };
}

namespace InhCtor {
  template<int> struct X {};
  struct Base {
    Base(X<0>) noexcept(true);
    Base(X<1>) noexcept(false);
    Base(X<2>) throw(X<2>);
    template<typename T> Base(T) throw(T);
  };
  template<typename T> struct Throw {
    Throw() throw(T);
  };
  struct Derived1 : Base, X<5> {
    using Base::Base;
    int n;
  };
  struct Derived2 : Base, Throw<X<3>> {
    using Base::Base;
  };
  struct Derived3 : Base {
    using Base::Base;
    Throw<X<4>> x;
  };
  static_assert(noexcept(Derived1(X<0>())), "");
  static_assert(!noexcept(Derived1(X<1>())), "");
  static_assert(!noexcept(Derived1(X<2>())), "");
  static_assert(!noexcept(Derived2(X<0>())), "");
  static_assert(!noexcept(Derived3(X<0>())), "");
}