1// RUN: %check_clang_tidy -std=c++17-or-later %s modernize-use-scoped-lock %t -- -- -isystem %clang_tidy_headers -fno-delayed-template-parsing
2
3#include <mutex>
4
5void Positive() {
6 std::mutex m;
7 {
8 std::lock_guard<std::mutex> l(m);
9 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
10 // CHECK-FIXES: std::scoped_lock l(m);
11 }
12
13 {
14 std::lock_guard<std::mutex> l(m, std::adopt_lock);
15 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
16 // CHECK-FIXES: std::scoped_lock l(std::adopt_lock, m);
17 }
18
19 {
20 std::lock_guard<std::mutex> l1(m);
21 std::lock_guard<std::mutex> l2(m);
22 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
23 // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' declared here
24 }
25
26 {
27 std::lock_guard<std::mutex> l1(m), l2(m);
28 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
29 // CHECK-MESSAGES: :[[@LINE-2]]:40: note: additional 'std::lock_guard' declared here
30 }
31
32 {
33 std::lock_guard<std::mutex> l1(m), l2(m), l3(m);
34 std::lock_guard<std::mutex> l4(m);
35 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
36 // CHECK-MESSAGES: :[[@LINE-3]]:40: note: additional 'std::lock_guard' declared here
37 // CHECK-MESSAGES: :[[@LINE-4]]:47: note: additional 'std::lock_guard' declared here
38 // CHECK-MESSAGES: :[[@LINE-4]]:33: note: additional 'std::lock_guard' declared here
39 }
40
41 {
42 std::lock(l1&: m, l2&: m);
43 std::lock_guard<std::mutex> l1(m, std::adopt_lock);
44 std::lock_guard<std::mutex> l2(m, std::adopt_lock);
45 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
46 // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' declared here
47 int a = 0;
48 std::lock_guard<std::mutex> l3(m);
49 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
50 // CHECK-FIXES: std::scoped_lock l3(m);
51 int b = 0;
52 std::lock_guard<std::mutex> l4(m, std::adopt_lock);
53 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
54 // CHECK-FIXES: std::scoped_lock l4(std::adopt_lock, m);
55 }
56}
57
58
59std::mutex p_m1;
60void PositiveShortFunction() {
61 std::lock_guard<std::mutex> l(p_m1);
62 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
63 // CHECK-FIXES: std::scoped_lock l(p_m1);
64}
65
66
67void PositiveNested() {
68 std::mutex m1;
69 if (true) {
70 std::lock_guard<std::mutex> l(m1);
71 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
72 // CHECK-FIXES: std::scoped_lock l(m1);
73 {
74 std::lock_guard<std::mutex> l2(m1);
75 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
76 // CHECK-FIXES: std::scoped_lock l2(m1);
77 {
78 std::lock_guard<std::mutex> l3(m1);
79 std::lock_guard<std::mutex> l4(m1);
80 // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
81 // CHECK-MESSAGES: :[[@LINE-2]]:37: note: additional 'std::lock_guard' declared here
82 }
83 {
84 std::lock_guard<std::mutex> l2(m1);
85 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
86 // CHECK-FIXES: std::scoped_lock l2(m1);
87 }
88 }
89 }
90 std::lock_guard<std::mutex> l(m1);
91 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
92 // CHECK-FIXES: std::scoped_lock l(m1);
93}
94
95
96void PositiveInsideArg(std::mutex &m1, std::mutex &m2, std::mutex &m3) {
97 std::lock_guard<std::mutex> l1(m1);
98 std::lock_guard<std::mutex> l2(m2);
99 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
100 // CHECK-MESSAGES: :[[@LINE-2]]:31: note: additional 'std::lock_guard' declared here
101 int a = 0;
102 std::lock_guard<std::mutex> l3(m3);
103 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
104 // CHECK-FIXES: std::scoped_lock l3(m3);
105}
106
107
108void PositiveInsideConditional() {
109 std::mutex m1;
110 if (true) {
111 std::lock_guard<std::mutex> l1(m1);
112 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
113 // CHECK-FIXES: std::scoped_lock l1(m1);
114 } else {
115 std::lock_guard<std::mutex> l1(m1);
116 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
117 // CHECK-FIXES: std::scoped_lock l1(m1);
118 }
119
120 while (true) {
121 std::lock_guard<std::mutex> l1(m1);
122 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
123 // CHECK-FIXES: std::scoped_lock l1(m1);
124 }
125
126 for (int i = 0; i < 10; ++i) {
127 std::lock_guard<std::mutex> l1(m1);
128 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
129 // CHECK-FIXES: std::scoped_lock l1(m1);
130 }
131}
132
133void PositiveLambda() {
134 std::mutex m;
135 std::lock_guard<std::mutex> l1(m);
136 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
137 // CHECK-FIXES: std::scoped_lock l1(m);
138 auto lambda1 = [&]() {
139 std::lock_guard<std::mutex> l1(m);
140 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
141 // CHECK-FIXES: std::scoped_lock l1(m);
142 };
143
144 std::lock_guard<std::mutex> l3(m);
145 std::lock_guard<std::mutex> l4(m);
146 // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
147 // CHECK-MESSAGES: :[[@LINE-2]]:31: note: additional 'std::lock_guard' declared here
148 auto lamda2 = [&]() {
149 std::lock_guard<std::mutex> l3(m);
150 std::lock_guard<std::mutex> l4(m);
151 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
152 // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' declared here
153 };
154
155 auto lamda3 = [&]() {
156 std::lock(l1&: m, l2&: m);
157 std::lock_guard<std::mutex> l1(m, std::adopt_lock);
158 std::lock_guard<std::mutex> l2(m, std::adopt_lock);
159 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
160 // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' declared here
161 int a = 0;
162 std::lock_guard<std::mutex> l3(m);
163 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
164 // CHECK-FIXES: std::scoped_lock l3(m);
165 int b = 0;
166 std::lock_guard<std::mutex> l4(m, std::adopt_lock);
167 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
168 // CHECK-FIXES: std::scoped_lock l4(std::adopt_lock, m);
169 };
170
171 auto lamda4 = [&]() {
172 std::lock_guard<std::mutex> l1(m);
173 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
174 // CHECK-FIXES: std::scoped_lock l1(m);
175 int a = 0;
176 std::lock_guard<std::mutex> l2(m);
177 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
178 // CHECK-FIXES: std::scoped_lock l2(m);
179 };
180}
181
182template <typename T>
183void PositiveTemplated() {
184 std::mutex m1, m2, m3;
185 {
186 std::lock_guard<std::mutex> l(m1);
187 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
188 // CHECK-FIXES: std::scoped_lock l(m1);
189 }
190
191 {
192 std::lock_guard<std::mutex> l1(m1);
193 std::lock_guard<std::mutex> l2(m2);
194 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
195 // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' declared here
196 }
197
198 {
199 std::lock(l1&: m1, l2&: m2);
200 std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
201 std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
202 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
203 // CHECK-MESSAGES: :[[@LINE-2]]:33: note: additional 'std::lock_guard' declared here
204 int a = 0;
205 std::lock_guard<std::mutex> l3(m3);
206 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
207 // CHECK-FIXES: std::scoped_lock l3(m3);
208 }
209}
210
211
212template <typename Mutex>
213void PositiveTemplatedMutex() {
214 Mutex m1, m2, m3;
215 {
216 std::lock_guard<Mutex> l(m1);
217 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
218 }
219
220 {
221 std::lock_guard<Mutex> l1(m1);
222 std::lock_guard<Mutex> l2(m2);
223 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
224 // CHECK-MESSAGES: :[[@LINE-2]]:28: note: additional 'std::lock_guard' declared here
225 }
226
227 {
228 std::lock(m1, m2);
229 std::lock_guard<Mutex> l1(m1, std::adopt_lock);
230 std::lock_guard<Mutex> l2(m2, std::adopt_lock);
231 // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
232 // CHECK-MESSAGES: :[[@LINE-2]]:28: note: additional 'std::lock_guard' declared here
233 int a = 0;
234 std::lock_guard<Mutex> l3(m3);
235 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
236 }
237}
238
239
240template <template <typename> typename Lock>
241void NegativeTemplate() {
242 std::mutex m1, m2;
243 {
244 Lock<std::mutex> l(m1);
245 }
246
247 {
248 Lock<std::mutex> l1(m1);
249 Lock<std::mutex> l2(m2);
250 }
251}
252
253void instantiate() {
254 NegativeTemplate<std::lock_guard>();
255}
256
257
258struct PositiveClass {
259 void Positive() {
260 {
261 std::lock_guard<std::mutex> l(m1);
262 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
263 // CHECK-FIXES: std::scoped_lock l(m1);
264 }
265
266 {
267 std::lock_guard<std::mutex> l1(m1);
268 std::lock_guard<std::mutex> l2(m2);
269 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
270 // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' declared here
271 }
272
273 {
274 std::lock(l1&: m1, l2&: m2);
275 std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
276 std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
277 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
278 // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' declared here
279 int a = 0;
280 std::lock_guard<std::mutex> l3(m3);
281 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
282 // CHECK-FIXES: std::scoped_lock l3(m3);
283 }
284 }
285
286 std::mutex m1;
287 std::mutex m2;
288 std::mutex m3;
289};
290
291
292template <typename T>
293struct PositiveTemplatedClass {
294 void Positive() {
295 {
296 std::lock_guard<std::mutex> l(m1);
297 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
298 // CHECK-FIXES: std::scoped_lock l(m1);
299 }
300
301 {
302 std::lock(l1&: m1, l2&: m2);
303 std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
304 std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
305 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
306 // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' declared here
307 int a = 0;
308 std::lock_guard<std::mutex> l3(m3);
309 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
310 // CHECK-FIXES: std::scoped_lock l3(m3);
311 }
312 }
313
314 template <typename... Ts>
315 void TemplatedPositive() {
316 {
317 std::lock_guard<std::mutex> l(m1);
318 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
319 // CHECK-FIXES: std::scoped_lock l(m1);
320 }
321
322 {
323 std::lock(l1&: m1, l2&: m2);
324 std::lock_guard<std::mutex> l1(m1, std::adopt_lock);
325 std::lock_guard<std::mutex> l2(m2, std::adopt_lock);
326 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
327 // CHECK-MESSAGES: :[[@LINE-2]]:35: note: additional 'std::lock_guard' declared here
328 int a = 0;
329 std::lock_guard<std::mutex> l3(m3);
330 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
331 // CHECK-FIXES: std::scoped_lock l3(m3);
332 }
333 }
334
335 std::mutex m1;
336 std::mutex m2;
337 std::mutex m3;
338};
339
340
341template <typename T>
342using Lock = std::lock_guard<T>;
343// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
344// CHECK-FIXES: using Lock = std::scoped_lock<T>;
345
346using LockM = std::lock_guard<std::mutex>;
347// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
348// CHECK-FIXES: using LockM = std::scoped_lock<std::mutex>;
349
350typedef std::lock_guard<std::mutex> LockDef;
351// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
352// CHECK-FIXES: typedef std::scoped_lock<std::mutex> LockDef;
353
354
355void PositiveUsingDecl() {
356 using std::lock_guard;
357 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
358 // CHECK-FIXES: using std::scoped_lock;
359
360 using LockMFun = std::lock_guard<std::mutex>;
361 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
362 // CHECK-FIXES: using LockMFun = std::scoped_lock<std::mutex>;
363
364 typedef std::lock_guard<std::mutex> LockDefFun;
365 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
366 // CHECK-FIXES: typedef std::scoped_lock<std::mutex> LockDefFun;
367}
368
369template <typename T>
370void PositiveUsingDeclTemplate() {
371 using std::lock_guard;
372 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
373 // CHECK-FIXES: using std::scoped_lock;
374
375 std::mutex m;
376 lock_guard<std::mutex> l(m);
377 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
378 // CHECK-FIXES: std::scoped_lock l(m);
379
380 using LockFunT = std::lock_guard<T>;
381 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
382 // CHECK-FIXES: using LockFunT = std::scoped_lock<T>;
383
384 using LockMFunT = std::lock_guard<std::mutex>;
385 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
386 // CHECK-FIXES: using LockMFunT = std::scoped_lock<std::mutex>;
387
388 typedef std::lock_guard<std::mutex> LockDefFunT;
389 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
390 // CHECK-FIXES: typedef std::scoped_lock<std::mutex> LockDefFunT;
391}
392
393void PositiveInUsingTypedefs() {
394 std::mutex m;
395
396 {
397 Lock<std::mutex> l(m);
398 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
399 // CHECK-FIXES: std::scoped_lock l(m);
400 }
401
402 {
403 LockM l(m);
404 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
405 // CHECK-FIXES: std::scoped_lock l(m);
406 }
407
408 {
409 LockDef l(m);
410 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
411 // CHECK-FIXES: std::scoped_lock l(m);
412 }
413
414 {
415 std::lock(l1&: m, l2&: m);
416 Lock<std::mutex> l1(m, std::adopt_lock);
417 LockM l2(m, std::adopt_lock);
418 LockDef l3(m), l4(m);
419 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
420 // CHECK-MESSAGES: :[[@LINE-3]]:11: note: additional 'std::lock_guard' declared here
421 // CHECK-MESSAGES: :[[@LINE-3]]:13: note: additional 'std::lock_guard' declared here
422 // CHECK-MESSAGES: :[[@LINE-4]]:20: note: additional 'std::lock_guard' declared here
423 int a = 0;
424 LockDef l5(m);
425 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
426 // CHECK-FIXES: std::scoped_lock l5(m);
427 }
428}
429
430template <typename Mutex>
431void PositiveInUsingTypedefsTemplated() {
432 Mutex m;
433
434 {
435 Lock<Mutex> l(m);
436 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
437 }
438
439 {
440 std::lock(m, m);
441 Lock<Mutex> l1(m, std::adopt_lock);
442 LockM l2(m, std::adopt_lock);
443 LockDef l3(m), l4(m);
444 // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use single 'std::scoped_lock' instead of multiple 'std::lock_guard'
445 // CHECK-MESSAGES: :[[@LINE-3]]:11: note: additional 'std::lock_guard' declared here
446 // CHECK-MESSAGES: :[[@LINE-3]]:13: note: additional 'std::lock_guard' declared here
447 // CHECK-MESSAGES: :[[@LINE-4]]:20: note: additional 'std::lock_guard' declared here
448 int a = 0;
449 LockDef l5(m);
450 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use 'std::scoped_lock' instead of 'std::lock_guard'
451 }
452}
453
454// Non-STD lock_guard.
455template <typename Mutex>
456struct lock_guard {
457 lock_guard(Mutex &m) { }
458 lock_guard(const lock_guard& ) = delete;
459};
460
461void NegativeNonStdLockGuard() {
462 std::mutex m;
463 {
464 lock_guard<std::mutex> l(m);
465 }
466
467 {
468 lock_guard<std::mutex> l1(m);
469 lock_guard<std::mutex> l2(m);
470 }
471}
472

source code of clang-tools-extra/test/clang-tidy/checkers/modernize/use-scoped-lock.cpp