1 // RUN: %check_clang_tidy -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs
2 // FIXME: Fix the checker to work in C++17 mode.
3
4 using int64_t = long long;
5
6 #include "absl/time/time.h"
7
8 template <typename T> struct ConvertibleTo {
9 operator T() const;
10 };
11
12 template <typename T>
13 ConvertibleTo<T> operator+(ConvertibleTo<T>, ConvertibleTo<T>);
14
15 template <typename T>
16 ConvertibleTo<T> operator*(ConvertibleTo<T>, ConvertibleTo<T>);
17
arithmeticOperatorBasicPositive()18 void arithmeticOperatorBasicPositive() {
19 absl::Duration d;
20 d *= ConvertibleTo<int64_t>();
21 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
22 // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int64_t>());
23 d /= ConvertibleTo<int64_t>();
24 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
25 // CHECK-FIXES: d /= static_cast<int64_t>(ConvertibleTo<int64_t>());
26 d = ConvertibleTo<int64_t>() * d;
27 // CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
28 // CHECK-FIXES: d = static_cast<int64_t>(ConvertibleTo<int64_t>()) * d;
29 d = d * ConvertibleTo<int64_t>();
30 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
31 // CHECK-FIXES: d = d * static_cast<int64_t>(ConvertibleTo<int64_t>());
32 d = d / ConvertibleTo<int64_t>();
33 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
34 // CHECK-FIXES: d = d / static_cast<int64_t>(ConvertibleTo<int64_t>());
35 d.operator*=(ConvertibleTo<int64_t>());
36 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
37 // CHECK-FIXES: d.operator*=(static_cast<int64_t>(ConvertibleTo<int64_t>()));
38 d.operator/=(ConvertibleTo<int64_t>());
39 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
40 // CHECK-FIXES: d.operator/=(static_cast<int64_t>(ConvertibleTo<int64_t>()));
41 d = operator*(ConvertibleTo<int64_t>(), d);
42 // CHECK-MESSAGES: [[@LINE-1]]:17: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
43 // CHECK-FIXES: d = operator*(static_cast<int64_t>(ConvertibleTo<int64_t>()), d);
44 d = operator*(d, ConvertibleTo<int64_t>());
45 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
46 // CHECK-FIXES: d = operator*(d, static_cast<int64_t>(ConvertibleTo<int64_t>()));
47 d = operator/(d, ConvertibleTo<int64_t>());
48 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
49 // CHECK-FIXES: d = operator/(d, static_cast<int64_t>(ConvertibleTo<int64_t>()));
50 ConvertibleTo<int64_t> c;
51 d *= (c + c) * c + c;
52 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
53 // CHECK-FIXES: d *= static_cast<int64_t>((c + c) * c + c)
54 d /= (c + c) * c + c;
55 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
56 // CHECK-FIXES: d /= static_cast<int64_t>((c + c) * c + c)
57 d = d * c * c;
58 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
59 // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
60 // CHECK-FIXES: d = d * static_cast<int64_t>(c) * static_cast<int64_t>(c)
61 d = c * d * c;
62 // CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
63 // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
64 // CHECK-FIXES: d = static_cast<int64_t>(c) * d * static_cast<int64_t>(c)
65 d = d / c * c;
66 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
67 // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
68 // CHECK-FIXES: d = d / static_cast<int64_t>(c) * static_cast<int64_t>(c)
69 }
70
arithmeticOperatorBasicNegative()71 void arithmeticOperatorBasicNegative() {
72 absl::Duration d;
73 d *= char{1};
74 d *= 1;
75 d *= int64_t{1};
76 d *= 1.0f;
77 d *= 1.0;
78 d *= 1.0l;
79 d /= char{1};
80 d /= 1;
81 d /= int64_t{1};
82 d /= 1.0f;
83 d /= 1.0;
84 d /= 1.0l;
85 d = d * char{1};
86 d = d * 1;
87 d = d * int64_t{1};
88 d = d * 1.0f;
89 d = d * 1.0;
90 d = d * 1.0l;
91 d = char{1} * d;
92 d = 1 * d;
93 d = int64_t{1} * d;
94 d = 1.0f * d;
95 d = 1.0 * d;
96 d = 1.0l * d;
97 d = d / char{1};
98 d = d / 1;
99 d = d / int64_t{1};
100 d = d / 1.0f;
101 d = d / 1.0;
102 d = d / 1.0l;
103
104 d *= static_cast<int>(ConvertibleTo<int>());
105 d *= (int)ConvertibleTo<int>();
106 d *= int(ConvertibleTo<int>());
107 d /= static_cast<int>(ConvertibleTo<int>());
108 d /= (int)ConvertibleTo<int>();
109 d /= int(ConvertibleTo<int>());
110 d = static_cast<int>(ConvertibleTo<int>()) * d;
111 d = (int)ConvertibleTo<int>() * d;
112 d = int(ConvertibleTo<int>()) * d;
113 d = d * static_cast<int>(ConvertibleTo<int>());
114 d = d * (int)ConvertibleTo<int>();
115 d = d * int(ConvertibleTo<int>());
116 d = d / static_cast<int>(ConvertibleTo<int>());
117 d = d / (int)ConvertibleTo<int>();
118 d = d / int(ConvertibleTo<int>());
119
120 d *= 1 + ConvertibleTo<int>();
121 d /= 1 + ConvertibleTo<int>();
122 d = (1 + ConvertibleTo<int>()) * d;
123 d = d * (1 + ConvertibleTo<int>());
124 d = d / (1 + ConvertibleTo<int>());
125 }
126
templateForOpsSpecialization(T)127 template <typename T> void templateForOpsSpecialization(T) {}
128 template <>
templateForOpsSpecialization(absl::Duration d)129 void templateForOpsSpecialization<absl::Duration>(absl::Duration d) {
130 d *= ConvertibleTo<int64_t>();
131 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
132 // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int64_t>());
133 }
134
arithmeticNonTypeTemplateParamSpecialization()135 template <int N> void arithmeticNonTypeTemplateParamSpecialization() {
136 absl::Duration d;
137 d *= N;
138 }
139
arithmeticNonTypeTemplateParamSpecialization()140 template <> void arithmeticNonTypeTemplateParamSpecialization<5>() {
141 absl::Duration d;
142 d *= ConvertibleTo<int>();
143 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
144 // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int>());
145 }
146
templateOpsFix()147 template <typename T> void templateOpsFix() {
148 absl::Duration d;
149 d *= ConvertibleTo<int64_t>();
150 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
151 // CHECK-FIXES: d *= static_cast<int64_t>(ConvertibleTo<int64_t>());
152 }
153
templateOpsWarnOnly(T t,U u)154 template <typename T, typename U> void templateOpsWarnOnly(T t, U u) {
155 t *= u;
156 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
157 absl::Duration d;
158 d *= u;
159 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
160 }
161
162 template <typename T> struct TemplateTypeOpsWarnOnly {
memberATemplateTypeOpsWarnOnly163 void memberA(T t) {
164 d *= t;
165 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
166 }
memberBTemplateTypeOpsWarnOnly167 template <typename U, typename V> void memberB(U u, V v) {
168 u *= v;
169 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
170 d *= v;
171 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
172 }
173
174 absl::Duration d;
175 };
176
177 template <typename T, typename U>
178 void templateOpsInstantiationBeforeDefinition(T t, U u);
179
arithmeticOperatorsInTemplates()180 void arithmeticOperatorsInTemplates() {
181 templateForOpsSpecialization(5);
182 templateForOpsSpecialization(absl::Duration());
183 arithmeticNonTypeTemplateParamSpecialization<1>();
184 arithmeticNonTypeTemplateParamSpecialization<5>();
185 templateOpsFix<int>();
186 templateOpsWarnOnly(absl::Duration(), ConvertibleTo<int>());
187 templateOpsInstantiationBeforeDefinition(absl::Duration(),
188 ConvertibleTo<int>());
189 TemplateTypeOpsWarnOnly<ConvertibleTo<int>> t;
190 t.memberA(ConvertibleTo<int>());
191 t.memberB(absl::Duration(), ConvertibleTo<int>());
192 }
193
194 template <typename T, typename U>
templateOpsInstantiationBeforeDefinition(T t,U u)195 void templateOpsInstantiationBeforeDefinition(T t, U u) {
196 t *= u;
197 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
198 absl::Duration d;
199 d *= u;
200 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
201 }
202
203 #define FUNCTION_MACRO(x) x
204 #define CONVERTIBLE_TMP ConvertibleTo<int>()
205 #define ONLY_WARN_INSIDE_MACRO_ARITHMETIC_OP d *= ConvertibleTo<int>()
206
207 #define T_OBJECT T()
208 #define T_CALL_EXPR d *= T()
209
arithmeticTemplateAndMacro()210 template <typename T> void arithmeticTemplateAndMacro() {
211 absl::Duration d;
212 d *= T_OBJECT;
213 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
214 d *= CONVERTIBLE_TMP;
215 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
216 // CHECK-FIXES: d *= static_cast<int64_t>(CONVERTIBLE_TMP);
217 T_CALL_EXPR;
218 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
219 }
220
221 #define TEMPLATE_MACRO(type) \
222 template <typename T> void TemplateInMacro(T t) { \
223 type d; \
224 d *= t; \
225 }
226
TEMPLATE_MACRO(absl::Duration)227 TEMPLATE_MACRO(absl::Duration)
228 // CHECK-MESSAGES: [[@LINE-1]]:1: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
229
230 void arithmeticOperatorsInMacros() {
231 absl::Duration d;
232 d = FUNCTION_MACRO(d * ConvertibleTo<int>());
233 // CHECK-MESSAGES: [[@LINE-1]]:26: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
234 // CHECK-FIXES: d = FUNCTION_MACRO(d * static_cast<int64_t>(ConvertibleTo<int>()));
235 d *= FUNCTION_MACRO(ConvertibleTo<int>());
236 // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
237 // CHECK-FIXES: d *= static_cast<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>()));
238 d *= CONVERTIBLE_TMP;
239 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
240 // CHECK-FIXES: d *= static_cast<int64_t>(CONVERTIBLE_TMP);
241 ONLY_WARN_INSIDE_MACRO_ARITHMETIC_OP;
242 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
243 arithmeticTemplateAndMacro<ConvertibleTo<int>>();
244 TemplateInMacro(ConvertibleTo<int>());
245 }
246
factoryFunctionPositive()247 void factoryFunctionPositive() {
248 // User defined conversion:
249 (void)absl::Nanoseconds(ConvertibleTo<int64_t>());
250 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
251 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
252 (void)absl::Microseconds(ConvertibleTo<int64_t>());
253 // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
254 // CHECK-FIXES: (void)absl::Microseconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
255 (void)absl::Milliseconds(ConvertibleTo<int64_t>());
256 // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
257 // CHECK-FIXES: (void)absl::Milliseconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
258 (void)absl::Seconds(ConvertibleTo<int64_t>());
259 // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
260 // CHECK-FIXES: (void)absl::Seconds(static_cast<int64_t>(ConvertibleTo<int64_t>()));
261 (void)absl::Minutes(ConvertibleTo<int64_t>());
262 // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
263 // CHECK-FIXES: (void)absl::Minutes(static_cast<int64_t>(ConvertibleTo<int64_t>()));
264 (void)absl::Hours(ConvertibleTo<int64_t>());
265 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
266 // CHECK-FIXES: (void)absl::Hours(static_cast<int64_t>(ConvertibleTo<int64_t>()));
267
268 // User defined conversion to integral type, followed by built-in conversion:
269 (void)absl::Nanoseconds(ConvertibleTo<char>());
270 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
271 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<char>()));
272 (void)absl::Microseconds(ConvertibleTo<char>());
273 // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
274 // CHECK-FIXES: (void)absl::Microseconds(static_cast<int64_t>(ConvertibleTo<char>()));
275 (void)absl::Milliseconds(ConvertibleTo<char>());
276 // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
277 // CHECK-FIXES: (void)absl::Milliseconds(static_cast<int64_t>(ConvertibleTo<char>()));
278 (void)absl::Seconds(ConvertibleTo<char>());
279 // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
280 // CHECK-FIXES: (void)absl::Seconds(static_cast<int64_t>(ConvertibleTo<char>()));
281 (void)absl::Minutes(ConvertibleTo<char>());
282 // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
283 // CHECK-FIXES: (void)absl::Minutes(static_cast<int64_t>(ConvertibleTo<char>()));
284 (void)absl::Hours(ConvertibleTo<char>());
285 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
286 // CHECK-FIXES: (void)absl::Hours(static_cast<int64_t>(ConvertibleTo<char>()));
287
288 // User defined conversion to floating point type, followed by built-in conversion:
289 (void)absl::Nanoseconds(ConvertibleTo<float>());
290 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
291 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<float>()));
292 (void)absl::Microseconds(ConvertibleTo<float>());
293 // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
294 // CHECK-FIXES: (void)absl::Microseconds(static_cast<int64_t>(ConvertibleTo<float>()));
295 (void)absl::Milliseconds(ConvertibleTo<float>());
296 // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
297 // CHECK-FIXES: (void)absl::Milliseconds(static_cast<int64_t>(ConvertibleTo<float>()));
298 (void)absl::Seconds(ConvertibleTo<float>());
299 // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
300 // CHECK-FIXES: (void)absl::Seconds(static_cast<int64_t>(ConvertibleTo<float>()));
301 (void)absl::Minutes(ConvertibleTo<float>());
302 // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
303 // CHECK-FIXES: (void)absl::Minutes(static_cast<int64_t>(ConvertibleTo<float>()));
304 (void)absl::Hours(ConvertibleTo<float>());
305 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
306 // CHECK-FIXES: (void)absl::Hours(static_cast<int64_t>(ConvertibleTo<float>()));
307 }
308
factoryFunctionNegative()309 void factoryFunctionNegative() {
310 (void)absl::Nanoseconds(char{1});
311 (void)absl::Nanoseconds(1);
312 (void)absl::Nanoseconds(int64_t{1});
313 (void)absl::Nanoseconds(1.0f);
314 (void)absl::Microseconds(char{1});
315 (void)absl::Microseconds(1);
316 (void)absl::Microseconds(int64_t{1});
317 (void)absl::Microseconds(1.0f);
318 (void)absl::Milliseconds(char{1});
319 (void)absl::Milliseconds(1);
320 (void)absl::Milliseconds(int64_t{1});
321 (void)absl::Milliseconds(1.0f);
322 (void)absl::Seconds(char{1});
323 (void)absl::Seconds(1);
324 (void)absl::Seconds(int64_t{1});
325 (void)absl::Seconds(1.0f);
326 (void)absl::Minutes(char{1});
327 (void)absl::Minutes(1);
328 (void)absl::Minutes(int64_t{1});
329 (void)absl::Minutes(1.0f);
330 (void)absl::Hours(char{1});
331 (void)absl::Hours(1);
332 (void)absl::Hours(int64_t{1});
333 (void)absl::Hours(1.0f);
334
335 (void)absl::Nanoseconds(static_cast<int>(ConvertibleTo<int>()));
336 (void)absl::Microseconds(static_cast<int>(ConvertibleTo<int>()));
337 (void)absl::Milliseconds(static_cast<int>(ConvertibleTo<int>()));
338 (void)absl::Seconds(static_cast<int>(ConvertibleTo<int>()));
339 (void)absl::Minutes(static_cast<int>(ConvertibleTo<int>()));
340 (void)absl::Hours(static_cast<int>(ConvertibleTo<int>()));
341 }
342
templateForFactorySpecialization(T)343 template <typename T> void templateForFactorySpecialization(T) {}
templateForFactorySpecialization(ConvertibleTo<int> c)344 template <> void templateForFactorySpecialization<ConvertibleTo<int>>(ConvertibleTo<int> c) {
345 (void)absl::Nanoseconds(c);
346 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
347 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(c));
348 }
349
factoryNonTypeTemplateParamSpecialization()350 template <int N> void factoryNonTypeTemplateParamSpecialization() {
351 (void)absl::Nanoseconds(N);
352 }
353
factoryNonTypeTemplateParamSpecialization()354 template <> void factoryNonTypeTemplateParamSpecialization<5>() {
355 (void)absl::Nanoseconds(ConvertibleTo<int>());
356 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
357 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<int>()));
358 }
359
templateFactoryFix()360 template <typename T> void templateFactoryFix() {
361 (void)absl::Nanoseconds(ConvertibleTo<int>());
362 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
363 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(ConvertibleTo<int>()));
364 }
365
templateFactoryWarnOnly(T t)366 template <typename T> void templateFactoryWarnOnly(T t) {
367 (void)absl::Nanoseconds(t);
368 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
369 }
370
371 template <typename T> void templateFactoryInstantiationBeforeDefinition(T t);
372
373 template <typename T> struct TemplateTypeFactoryWarnOnly {
memberATemplateTypeFactoryWarnOnly374 void memberA(T t) {
375 (void)absl::Nanoseconds(t);
376 // CHECK-MESSAGES: [[@LINE-1]]:29: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
377 }
memberBTemplateTypeFactoryWarnOnly378 template <typename U> void memberB(U u) {
379 (void)absl::Nanoseconds(u);
380 // CHECK-MESSAGES: [[@LINE-1]]:29: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
381 }
382 };
383
factoryInTemplates()384 void factoryInTemplates() {
385 templateForFactorySpecialization(5);
386 templateForFactorySpecialization(ConvertibleTo<int>());
387 factoryNonTypeTemplateParamSpecialization<1>();
388 factoryNonTypeTemplateParamSpecialization<5>();
389 templateFactoryFix<int>();
390 templateFactoryWarnOnly(ConvertibleTo<int>());
391 templateFactoryInstantiationBeforeDefinition(ConvertibleTo<int>());
392 TemplateTypeFactoryWarnOnly<ConvertibleTo<int>> t;
393 t.memberA(ConvertibleTo<int>());
394 t.memberB(ConvertibleTo<int>());
395 }
396
templateFactoryInstantiationBeforeDefinition(T t)397 template <typename T> void templateFactoryInstantiationBeforeDefinition(T t) {
398 (void)absl::Nanoseconds(t);
399 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
400 }
401
402 #define ONLY_WARN_INSIDE_MACRO_FACTORY \
403 (void)absl::Nanoseconds(ConvertibleTo<int>())
404 #define T_CALL_FACTORTY_INSIDE_MACRO (void)absl::Nanoseconds(T())
405
factoryTemplateAndMacro()406 template <typename T> void factoryTemplateAndMacro() {
407 (void)absl::Nanoseconds(T_OBJECT);
408 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
409 (void)absl::Nanoseconds(CONVERTIBLE_TMP);
410 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
411 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP))
412 T_CALL_FACTORTY_INSIDE_MACRO;
413 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
414 }
415
416 #define TEMPLATE_FACTORY_MACRO(factory) \
417 template <typename T> void TemplateFactoryInMacro(T t) { (void)factory(t); }
418
TEMPLATE_FACTORY_MACRO(absl::Nanoseconds)419 TEMPLATE_FACTORY_MACRO(absl::Nanoseconds)
420 // CHECK-MESSAGES: [[@LINE-1]]:1: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
421
422 void factoryInMacros() {
423 (void)absl::Nanoseconds(FUNCTION_MACRO(ConvertibleTo<int>()));
424 // CHECK-MESSAGES: [[@LINE-1]]:42: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
425 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>())));
426 (void)absl::Nanoseconds(CONVERTIBLE_TMP);
427 // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
428 // CHECK-FIXES: (void)absl::Nanoseconds(static_cast<int64_t>(CONVERTIBLE_TMP))
429 ONLY_WARN_INSIDE_MACRO_FACTORY;
430 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead
431 factoryTemplateAndMacro<ConvertibleTo<int>>();
432 TemplateFactoryInMacro(ConvertibleTo<int>());
433 }
434
435 // This is a reduced test-case for PR39949 and manifested in this check.
436 namespace std {
437 template <typename _Tp>
438 _Tp declval();
439
440 template <typename _Functor, typename... _ArgTypes>
441 struct __res {
442 template <typename... _Args>
443 static decltype(declval<_Functor>()(_Args()...)) _S_test(int);
444
445 template <typename...>
446 static void _S_test(...);
447
448 typedef decltype(_S_test<_ArgTypes...>(0)) type;
449 };
450
451 template <typename>
452 struct function;
453
454 template <typename... _ArgTypes>
455 struct function<void(_ArgTypes...)> {
456 template <typename _Functor,
457 typename = typename __res<_Functor, _ArgTypes...>::type>
functionstd::function458 function(_Functor) {}
459 };
460 } // namespace std
461
462 typedef std::function<void(void)> F;
463
foo()464 F foo() {
465 return F([] {});
466 }
467