android-comparison-in-temp-failure-retry.c
6.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// RUN: %check_clang_tidy %s android-comparison-in-temp-failure-retry %t
#define TEMP_FAILURE_RETRY(x) \
({ \
typeof(x) __z; \
do \
__z = (x); \
while (__z == -1); \
__z; \
})
int foo();
int bar(int a);
void test() {
int i;
TEMP_FAILURE_RETRY((i = foo()));
TEMP_FAILURE_RETRY(foo());
TEMP_FAILURE_RETRY((foo()));
TEMP_FAILURE_RETRY(foo() == 1);
// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: top-level comparison in TEMP_FAILURE_RETRY [android-comparison-in-temp-failure-retry]
TEMP_FAILURE_RETRY((foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: top-level comparison in TEMP_FAILURE_RETRY
TEMP_FAILURE_RETRY((int)(foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
TEMP_FAILURE_RETRY(bar(foo() == 1));
TEMP_FAILURE_RETRY((bar(foo() == 1)));
TEMP_FAILURE_RETRY((bar(foo() == 1)) == 1);
// CHECK-MESSAGES: :[[@LINE-1]]:40: warning: top-level comparison in TEMP_FAILURE_RETRY
TEMP_FAILURE_RETRY(((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:41: warning: top-level comparison in TEMP_FAILURE_RETRY
TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY
#define INDIRECT TEMP_FAILURE_RETRY
INDIRECT(foo());
INDIRECT((foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: top-level comparison in TEMP_FAILURE_RETRY
INDIRECT(bar(foo() == 1));
INDIRECT((int)((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: top-level comparison in TEMP_FAILURE_RETRY
#define TFR(x) TEMP_FAILURE_RETRY(x)
TFR(foo());
TFR((foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: top-level comparison in TEMP_FAILURE_RETRY
TFR(bar(foo() == 1));
TFR((int)((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: top-level comparison in TEMP_FAILURE_RETRY
#define ADD_TFR(x) (1 + TEMP_FAILURE_RETRY(x) + 1)
ADD_TFR(foo());
ADD_TFR(foo() == 1);
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: top-level comparison in TEMP_FAILURE_RETRY
ADD_TFR(bar(foo() == 1));
ADD_TFR((int)((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: top-level comparison in TEMP_FAILURE_RETRY
#define ADDP_TFR(x) (1 + TEMP_FAILURE_RETRY((x)) + 1)
ADDP_TFR(foo());
ADDP_TFR((foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: top-level comparison in TEMP_FAILURE_RETRY
ADDP_TFR(bar(foo() == 1));
ADDP_TFR((int)((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: top-level comparison in TEMP_FAILURE_RETRY
#define MACRO TEMP_FAILURE_RETRY(foo() == 1)
MACRO;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: top-level comparison in TEMP_FAILURE_RETRY
// Be sure that being a macro arg doesn't mess with this.
#define ID(x) (x)
ID(ADDP_TFR(bar(foo() == 1)));
ID(ADDP_TFR(bar(foo() == 1) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: top-level comparison in TEMP_FAILURE_RETRY
ID(MACRO);
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: top-level comparison in TEMP_FAILURE_RETRY
#define CMP(x) x == 1
TEMP_FAILURE_RETRY(CMP(foo()));
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: top-level comparison in TEMP_FAILURE_RETRY
}
// Be sure that it works inside of things like loops, if statements, etc.
void control_flow() {
do {
if (TEMP_FAILURE_RETRY(foo())) {
}
if (TEMP_FAILURE_RETRY(foo() == 1)) {
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
}
if (TEMP_FAILURE_RETRY(bar(foo() == 1))) {
}
if (TEMP_FAILURE_RETRY(bar(foo() == 1) == 1)) {
// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: top-level comparison in TEMP_FAILURE_RETRY
}
} while (TEMP_FAILURE_RETRY(foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: top-level comparison in TEMP_FAILURE_RETRY
}
void with_nondependent_variable_type() {
#undef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(x) \
({ \
long int __z; \
do \
__z = (x); \
while (__z == -1); \
__z; \
})
TEMP_FAILURE_RETRY((foo()));
TEMP_FAILURE_RETRY((int)(foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
TEMP_FAILURE_RETRY((bar(foo() == 1)));
TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY
}
// I can't find a case where TEMP_FAILURE_RETRY is implemented like this, but if
// we can cheaply support it, I don't see why not.
void obscured_temp_failure_retry() {
#undef TEMP_FAILURE_RETRY
#define IMPL(x) \
({ \
typeof(x) __z; \
do \
__z = (x); \
while (__z == -1); \
__z; \
})
#define IMPL2(x) IMPL(x)
#define TEMP_FAILURE_RETRY(x) IMPL2(x)
TEMP_FAILURE_RETRY((foo()));
TEMP_FAILURE_RETRY((int)(foo() == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: top-level comparison in TEMP_FAILURE_RETRY
TEMP_FAILURE_RETRY((bar(foo() == 1)));
TEMP_FAILURE_RETRY((int)((bar(foo() == 1)) == 1));
// CHECK-MESSAGES: :[[@LINE-1]]:46: warning: top-level comparison in TEMP_FAILURE_RETRY
}