1 // RUN: %check_clang_tidy -std=c++11,c++14 %s cert-err60-cpp %t -- -- -fcxx-exceptions
2 // FIXME: Split off parts of this test that rely on dynamic exception
3 // specifications, and run this test in all language modes.
4 
5 struct S {};
6 struct T : S {};
7 struct U {
8   U() = default;
9   U(const U&) = default;
10 };
11 
12 struct V {
13   V() = default;
14   V(const V&) noexcept;
15 };
16 
17 struct W {
18   W() = default;
19   W(const W&) noexcept(false);
20 };
21 
22 struct X {
23   X() = default;
XX24   X(const X&) {}
25 };
26 
27 struct Y {
28   Y() = default;
29   Y(const Y&) throw();
30 };
31 
32 struct Z {
33   Z() = default;
34   Z(const Z&) throw(int);
35 };
36 
37 void g() noexcept(false);
38 
39 struct A {
40   A() = default;
41   A(const A&) noexcept(noexcept(g()));
42 };
43 
44 struct B {
45   B() = default;
46   B(const B&) = default;
47   B(const A&) noexcept(false);
48 };
49 
50 class C {
51   W M; // W is not no-throw copy constructible
52 public:
53   C() = default;
54   C(const C&) = default;
55 };
56 
57 struct D {
58   D() = default;
59   D(const D&) noexcept(false);
60   D(D&) noexcept(true);
61 };
62 
63 struct E {
64   E() = default;
65   E(E&) noexcept(true);
66   E(const E&) noexcept(false);
67 };
68 
69 struct Allocates {
70   int *x;
AllocatesAllocates71   Allocates() : x(new int(0)) {}
AllocatesAllocates72   Allocates(const Allocates &other) : x(new int(*other.x)) {}
73 };
74 
75 struct OptionallyAllocates {
76   int *x;
OptionallyAllocatesOptionallyAllocates77   OptionallyAllocates() : x(new int(0)) {}
OptionallyAllocatesOptionallyAllocates78   OptionallyAllocates(const Allocates &other) noexcept(true) {
79     try {
80       x = new int(*other.x);
81     } catch (...) {
82       x = nullptr;
83     }
84   }
85 };
86 
f()87 void f() {
88   throw 12; // ok
89   throw "test"; // ok
90   throw S(); // ok
91   throw T(); // ok
92   throw U(); // ok
93   throw V(); // ok
94   throw W(); // match, noexcept(false)
95   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible [cert-err60-cpp]
96   throw X(); // match, no noexcept clause, nontrivial
97   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
98   throw Y(); // ok
99   throw Z(); // match, throw(int)
100   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
101   throw A(); // match, noexcept(false)
102   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
103   throw B(); // ok
104   throw C(); // match, C has a member variable that makes it throwing on copy
105   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
106   throw D(); // match, has throwing copy constructor
107   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
108   throw E(); // match, has throwing copy constructor
109   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
110   throw Allocates(); // match, copy constructor throws
111   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
112   throw OptionallyAllocates(); // ok
113 }
114 
115 namespace PR25574 {
116 struct B {
117   B(const B&) noexcept;
118 };
119 
120 struct D : B {
121   D();
122   virtual ~D() noexcept;
123 };
124 
125 template <typename T>
f()126 void f() {
127   throw D();
128 }
129 }
130