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 | // FIXME: Fix the checker to work in C++17 or later mode. |
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; |
24 | 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; |
71 | Allocates() : x(new int(0)) {} |
72 | Allocates(const Allocates &other) : x(new int(*other.x)) {} |
73 | }; |
74 | |
75 | struct OptionallyAllocates { |
76 | int *x; |
77 | OptionallyAllocates() : x(new int(0)) {} |
78 | OptionallyAllocates(const Allocates &other) noexcept(true) { |
79 | try { |
80 | x = new int(*other.x); |
81 | } catch (...) { |
82 | x = nullptr; |
83 | } |
84 | } |
85 | }; |
86 | |
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> |
126 | void f() { |
127 | throw D(); |
128 | } |
129 | } |
130 | |