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