1*852bf52cSBalázs Kéri // RUN: %check_clang_tidy -std=c++11 -check-suffixes=ALL,CPP11 %s bugprone-multiple-new-in-one-expression %t -- -- -target x86_64-unknown-unknown
2*852bf52cSBalázs Kéri // RUN: %check_clang_tidy -std=c++17 -check-suffixes=ALL,CPP17 %s bugprone-multiple-new-in-one-expression %t -- -- -target x86_64-unknown-unknown
3*852bf52cSBalázs Kéri 
4*852bf52cSBalázs Kéri namespace std {
5*852bf52cSBalázs Kéri typedef __typeof__(sizeof(0)) size_t;
6*852bf52cSBalázs Kéri enum class align_val_t : std::size_t {};
7*852bf52cSBalázs Kéri class exception {};
8*852bf52cSBalázs Kéri class bad_alloc : public exception {};
9*852bf52cSBalázs Kéri struct nothrow_t {};
10*852bf52cSBalázs Kéri extern const nothrow_t nothrow;
11*852bf52cSBalázs Kéri } // namespace std
12*852bf52cSBalázs Kéri 
13*852bf52cSBalázs Kéri void *operator new(std::size_t, const std::nothrow_t &) noexcept;
14*852bf52cSBalázs Kéri void *operator new(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept;
15*852bf52cSBalázs Kéri void *operator new(std::size_t, void *) noexcept;
16*852bf52cSBalázs Kéri void *operator new(std::size_t, char);
17*852bf52cSBalázs Kéri 
18*852bf52cSBalázs Kéri struct B;
19*852bf52cSBalázs Kéri 
20*852bf52cSBalázs Kéri struct A { int VarI; int *PtrI; B *PtrB; };
21*852bf52cSBalázs Kéri 
22*852bf52cSBalázs Kéri struct B { int VarI; };
23*852bf52cSBalázs Kéri 
24*852bf52cSBalázs Kéri struct G {
GG25*852bf52cSBalázs Kéri   G(A*, B*) {}
operator +=G26*852bf52cSBalázs Kéri   int operator+=(A *) { return 3; };
27*852bf52cSBalázs Kéri };
28*852bf52cSBalázs Kéri 
29*852bf52cSBalázs Kéri struct H {
30*852bf52cSBalázs Kéri   int *a;
31*852bf52cSBalázs Kéri   int *b;
32*852bf52cSBalázs Kéri };
33*852bf52cSBalázs Kéri 
34*852bf52cSBalázs Kéri int f(int);
35*852bf52cSBalázs Kéri int f(A*);
36*852bf52cSBalázs Kéri int f(A*, B*);
37*852bf52cSBalázs Kéri int f(int, B*);
38*852bf52cSBalázs Kéri int f(G, G);
39*852bf52cSBalázs Kéri int f(B*);
40*852bf52cSBalázs Kéri int f(const H &);
41*852bf52cSBalázs Kéri void f1(void *, void *);
42*852bf52cSBalázs Kéri A *g(A *);
43*852bf52cSBalázs Kéri 
44*852bf52cSBalázs Kéri G operator+(const G&, const G&);
45*852bf52cSBalázs Kéri 
test_function_parameter(A * XA,B * XB)46*852bf52cSBalázs Kéri void test_function_parameter(A *XA, B *XB) {
47*852bf52cSBalázs Kéri   (void)f(new A, new B);
48*852bf52cSBalázs Kéri   try {
49*852bf52cSBalázs Kéri     (void)f(new A, new B);
50*852bf52cSBalázs Kéri   }
51*852bf52cSBalázs Kéri   catch (A) {};
52*852bf52cSBalázs Kéri   try {
53*852bf52cSBalázs Kéri     (void)f(new A, new B);
54*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception; order of these allocations is undefined [
55*852bf52cSBalázs Kéri     (void)f(f(new A, new B));
56*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
57*852bf52cSBalázs Kéri     int X = f(new A, new B);
58*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
59*852bf52cSBalázs Kéri     X = f(new A, new B);
60*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
61*852bf52cSBalázs Kéri     X = 1 + f(new A, new B);
62*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
63*852bf52cSBalázs Kéri 
64*852bf52cSBalázs Kéri     (void)f(g(new A), new B);
65*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
66*852bf52cSBalázs Kéri 
67*852bf52cSBalázs Kéri     (void)f(1 + f(new A), new B);
68*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
69*852bf52cSBalázs Kéri     (void)f(XA = new A, new B);
70*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:18: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
71*852bf52cSBalázs Kéri     (void)f(1 + f(new A), XB = new B);
72*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:19: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
73*852bf52cSBalázs Kéri   }
74*852bf52cSBalázs Kéri   catch (std::exception) {}
75*852bf52cSBalázs Kéri }
76*852bf52cSBalázs Kéri 
test_operator(G * G1)77*852bf52cSBalázs Kéri void test_operator(G *G1) {
78*852bf52cSBalázs Kéri   (void)(f(new A) + f(new B));
79*852bf52cSBalázs Kéri   try {
80*852bf52cSBalázs Kéri     (void)(f(new A) + f(new B));
81*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
82*852bf52cSBalázs Kéri     (void)f(f(new A) + f(new B));
83*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
84*852bf52cSBalázs Kéri     int X = f(new A) + f(new B);
85*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
86*852bf52cSBalázs Kéri     X = f(new A) + f(new B);
87*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
88*852bf52cSBalázs Kéri     X = 1 + f(new A) + 1 + f(new B);
89*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:15: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
90*852bf52cSBalázs Kéri 
91*852bf52cSBalázs Kéri     (void)(f(g(new A)) + f(new B));
92*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:16: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
93*852bf52cSBalázs Kéri 
94*852bf52cSBalázs Kéri     (void)(f(1 + f(new A)) + f(new B));
95*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:20: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
96*852bf52cSBalázs Kéri     (void)(f(1 + f(new A)) + f(1 + f(new B)));
97*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:20: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
98*852bf52cSBalázs Kéri 
99*852bf52cSBalázs Kéri     (void)((new A)->VarI + (new A)->VarI);
100*852bf52cSBalázs Kéri 
101*852bf52cSBalázs Kéri     (void)(f(new A) + ((*G1) += new A));
102*852bf52cSBalázs Kéri      // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
103*852bf52cSBalázs Kéri   }
104*852bf52cSBalázs Kéri   catch (std::bad_alloc) {}
105*852bf52cSBalázs Kéri }
106*852bf52cSBalázs Kéri 
test_construct()107*852bf52cSBalázs Kéri void test_construct() {
108*852bf52cSBalázs Kéri   (void)(G(new A, new B));
109*852bf52cSBalázs Kéri   try {
110*852bf52cSBalázs Kéri     (void)(G(new A, new B));
111*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
112*852bf52cSBalázs Kéri     (void)(G(new A, nullptr) + G(nullptr, new B));
113*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
114*852bf52cSBalázs Kéri     f(G(new A, nullptr), G(new A, nullptr));
115*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:9: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
116*852bf52cSBalázs Kéri 
117*852bf52cSBalázs Kéri     (void)new G(new A, nullptr);
118*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
119*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:11: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
120*852bf52cSBalázs Kéri     (void)new G(nullptr, (new A)->PtrB);
121*852bf52cSBalázs Kéri     G *Z = new G(new A, nullptr);
122*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:12: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
123*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:12: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
124*852bf52cSBalázs Kéri     Z = new G(g(new A), nullptr);
125*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:9: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
126*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:9: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
127*852bf52cSBalázs Kéri     G *Z1, *Z2 = new G(nullptr, (new A)->PtrB), *Z3;
128*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP11: :[[@LINE-1]]:18: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
129*852bf52cSBalázs Kéri     // CHECK-MESSAGES-CPP17: :[[@LINE-2]]:18: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception [
130*852bf52cSBalázs Kéri  }
131*852bf52cSBalázs Kéri   catch (const std::bad_alloc &) {}
132*852bf52cSBalázs Kéri }
133*852bf52cSBalázs Kéri 
test_new_assign()134*852bf52cSBalázs Kéri void test_new_assign() {
135*852bf52cSBalázs Kéri   A *X, *Y;
136*852bf52cSBalázs Kéri   (X = new A)->VarI = (Y = new A)->VarI;
137*852bf52cSBalázs Kéri   try {
138*852bf52cSBalázs Kéri     (X = new A)->VarI = (Y = new A)->VarI;
139*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
140*852bf52cSBalázs Kéri     (new A)->VarI = (Y = new A)->VarI;
141*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
142*852bf52cSBalázs Kéri     (X = new A)->VarI = (new A)->VarI;
143*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
144*852bf52cSBalázs Kéri     (new A)->VarI = (new A)->VarI;
145*852bf52cSBalázs Kéri     (new A)->PtrI = new int;
146*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:6: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
147*852bf52cSBalázs Kéri     (X = new A)->VarI += (new A)->VarI;
148*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:10: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
149*852bf52cSBalázs Kéri   }
150*852bf52cSBalázs Kéri   catch (...) {}
151*852bf52cSBalázs Kéri }
152*852bf52cSBalázs Kéri 
test_operator_fixed_order(unsigned int L)153*852bf52cSBalázs Kéri void test_operator_fixed_order(unsigned int L) {
154*852bf52cSBalázs Kéri   (void)(f((f(new A) || f(0)) + f(new B[L])));
155*852bf52cSBalázs Kéri   try {
156*852bf52cSBalázs Kéri     (void)(f(new A) || f(new B));
157*852bf52cSBalázs Kéri     (void)(f(new A) && f(new B));
158*852bf52cSBalázs Kéri     (void)(f(new A) || f(new B) || f(new A));
159*852bf52cSBalázs Kéri 
160*852bf52cSBalázs Kéri     (void)(f(new A), f(new B));
161*852bf52cSBalázs Kéri 
162*852bf52cSBalázs Kéri     int Y = f(0, new B) ? f(new A) : f(new B);
163*852bf52cSBalázs Kéri     Y = f(new A) ? 1 : f(new B);
164*852bf52cSBalázs Kéri     Y = f(new A) ? f(new B) : 1;
165*852bf52cSBalázs Kéri 
166*852bf52cSBalázs Kéri     G g{new A, new B};
167*852bf52cSBalázs Kéri     H h{new int, new int};
168*852bf52cSBalázs Kéri     f({new int, new int});
169*852bf52cSBalázs Kéri     (void)f({new A, new B}, {nullptr, nullptr});
170*852bf52cSBalázs Kéri     (void)f({new A, new B}, {new A, nullptr});
171*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
172*852bf52cSBalázs Kéri 
173*852bf52cSBalázs Kéri     (void)(f((f(new A) || f(0)) + f(new B[L])));
174*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:17: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
175*852bf52cSBalázs Kéri   }
176*852bf52cSBalázs Kéri   catch (std::bad_alloc) {}
177*852bf52cSBalázs Kéri }
178*852bf52cSBalázs Kéri 
test_cast()179*852bf52cSBalázs Kéri void test_cast() {
180*852bf52cSBalázs Kéri   try {
181*852bf52cSBalázs Kéri     f1(static_cast<void *>(new A), new B);
182*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:28: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
183*852bf52cSBalázs Kéri   }
184*852bf52cSBalázs Kéri   catch (std::bad_alloc &) {}
185*852bf52cSBalázs Kéri }
186*852bf52cSBalázs Kéri 
test_nothrow(void * P)187*852bf52cSBalázs Kéri void test_nothrow(void *P) {
188*852bf52cSBalázs Kéri   try {
189*852bf52cSBalázs Kéri     (void)f(new(std::nothrow) A, new B);
190*852bf52cSBalázs Kéri     (void)f(new A, new(std::nothrow) B);
191*852bf52cSBalázs Kéri     (void)f(new(static_cast<std::align_val_t>(8), std::nothrow) A, new B);
192*852bf52cSBalázs Kéri     (void)f(new(P) A, new B);
193*852bf52cSBalázs Kéri     (void)f(new('a') A, new B);
194*852bf52cSBalázs Kéri     // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: memory allocation may leak if an other allocation is sequenced after it and throws an exception;
195*852bf52cSBalázs Kéri   }
196*852bf52cSBalázs Kéri   catch (std::exception) {}
197*852bf52cSBalázs Kéri }
198