1 // RUN: %check_clang_tidy %s bugprone-multiple-statement-macro %t
2 
3 void F();
4 
5 #define BAD_MACRO(x) \
6   F();               \
7   F()
8 
9 #define GOOD_MACRO(x) \
10   do {                \
11     F();              \
12     F();              \
13   } while (0)
14 
15 #define GOOD_MACRO2(x) F()
16 
17 #define GOOD_MACRO3(x) F();
18 
19 #define MACRO_ARG_MACRO(X) \
20   if (54)                  \
21   X(2)
22 
23 #define ALL_IN_MACRO(X) \
24   if (43)               \
25     F();                \
26   F()
27 
28 #define GOOD_NESTED(x)   \
29   if (x)            \
30     GOOD_MACRO3(x); \
31   F();
32 
33 #define IF(x) if(x)
34 
positives()35 void positives() {
36   if (1)
37     BAD_MACRO(1);
38   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used without braces; some statements will be unconditionally executed [bugprone-multiple-statement-macro]
39   if (1) {
40   } else
41     BAD_MACRO(1);
42   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used
43   while (1)
44     BAD_MACRO(1);
45   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used
46   for (;;)
47     BAD_MACRO(1);
48   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: multiple statement macro used
49 
50   MACRO_ARG_MACRO(BAD_MACRO);
51   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: multiple statement macro used
52   MACRO_ARG_MACRO(F(); int);
53   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: multiple statement macro used
54   IF(1) BAD_MACRO(1);
55   // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: multiple statement macro used
56 }
57 
negatives()58 void negatives() {
59   if (1) {
60     BAD_MACRO(1);
61   } else {
62     BAD_MACRO(1);
63   }
64   while (1) {
65     BAD_MACRO(1);
66   }
67   for (;;) {
68     BAD_MACRO(1);
69   }
70 
71   if (1)
72     GOOD_MACRO(1);
73   if (1) {
74     GOOD_MACRO(1);
75   }
76   if (1)
77     GOOD_MACRO2(1);
78   if (1)
79     GOOD_MACRO3(1);
80 
81   MACRO_ARG_MACRO(GOOD_MACRO);
82   ALL_IN_MACRO(1);
83 
84   IF(1) GOOD_MACRO(1);
85 }
86