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.
5struct S {};
6struct T : S {};
7struct U {
8 U() = default;
9 U(const U&) = default;
10};
11
12struct V {
13 V() = default;
14 V(const V&) noexcept;
15};
16
17struct W {
18 W() = default;
19 W(const W&) noexcept(false);
20};
21
22struct X {
23 X() = default;
24 X(const X&) {}
25};
26
27struct Y {
28 Y() = default;
29 Y(const Y&) throw();
30};
31
32struct Z {
33 Z() = default;
34 Z(const Z&) throw(int);
35};
36
37void g() noexcept(false);
38
39struct A {
40 A() = default;
41 A(const A&) noexcept(noexcept(g()));
42};
43
44struct B {
45 B() = default;
46 B(const B&) = default;
47 B(const A&) noexcept(false);
48};
49
50class C {
51 W M; // W is not no-throw copy constructible
52public:
53 C() = default;
54 C(const C&) = default;
55};
56
57struct D {
58 D() = default;
59 D(const D&) noexcept(false);
60 D(D&) noexcept(true);
61};
62
63struct E {
64 E() = default;
65 E(E&) noexcept(true);
66 E(const E&) noexcept(false);
67};
68
69struct Allocates {
70 int *x;
71 Allocates() : x(new int(0)) {}
72 Allocates(const Allocates &other) : x(new int(*other.x)) {}
73};
74
75struct 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
87void 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
115namespace PR25574 {
116struct B {
117 B(const B&) noexcept;
118};
119
120struct D : B {
121 D();
122 virtual ~D() noexcept;
123};
124
125template <typename T>
126void f() {
127 throw D();
128}
129}
130

source code of clang-tools-extra/test/clang-tidy/checkers/cert/throw-exception-type.cpp