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
  
     | 
    
      // RUN: %check_clang_tidy %s cert-err60-cpp %t -- -- -std=c++11 -fcxx-exceptions
struct S {};
struct T : S {};
struct U {
  U() = default;
  U(const U&) = default;
};
struct V {
  V() = default;
  V(const V&) noexcept;
};
struct W {
  W() = default;
  W(const W&) noexcept(false);
};
struct X {
  X() = default;
  X(const X&) {}
};
struct Y {
  Y() = default;
  Y(const Y&) throw();
};
struct Z {
  Z() = default;
  Z(const Z&) throw(int);
};
void g() noexcept(false);
struct A {
  A() = default;
  A(const A&) noexcept(noexcept(g()));
};
struct B {
  B() = default;
  B(const B&) = default;
  B(const A&) noexcept(false);
};
class C {
  W M; // W is not no-throw copy constructible
public:
  C() = default;
  C(const C&) = default;
};
struct D {
  D() = default;
  D(const D&) noexcept(false);
  D(D&) noexcept(true);
};
struct E {
  E() = default;
  E(E&) noexcept(true);
  E(const E&) noexcept(false);
};
struct Allocates {
  int *x;
  Allocates() : x(new int(0)) {}
  Allocates(const Allocates &other) : x(new int(*other.x)) {}
};
struct OptionallyAllocates {
  int *x;
  OptionallyAllocates() : x(new int(0)) {}
  OptionallyAllocates(const Allocates &other) noexcept(true) {
    try {
      x = new int(*other.x);
    } catch (...) {
      x = nullptr;
    }
  }
};
void f() {
  throw 12; // ok
  throw "test"; // ok
  throw S(); // ok
  throw T(); // ok
  throw U(); // ok
  throw V(); // ok
  throw W(); // match, noexcept(false)
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible [cert-err60-cpp]
  throw X(); // match, no noexcept clause, nontrivial
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
  throw Y(); // ok
  throw Z(); // match, throw(int)
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
  throw A(); // match, noexcept(false)
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
  throw B(); // ok
  throw C(); // match, C has a member variable that makes it throwing on copy
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
  throw D(); // match, has throwing copy constructor
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
  throw E(); // match, has throwing copy constructor
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
  throw Allocates(); // match, copy constructor throws
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
  throw OptionallyAllocates(); // ok
}
namespace PR25574 {
struct B {
  B(const B&) noexcept;
};
struct D : B {
  D();
  virtual ~D() noexcept;
};
template <typename T>
void f() {
  throw D();
}
}
 
     |