// RUN: %check_clang_tidy -std=c++11-or-later %s abseil-upgrade-duration-conversions %t -- -- -I%S/Inputs // FIXME: Fix the checker to work in C++17 mode. using int64_t = long long; #include "absl/time/time.h" template struct ConvertibleTo { operator T() const; }; template ConvertibleTo operator+(ConvertibleTo, ConvertibleTo); template ConvertibleTo operator*(ConvertibleTo, ConvertibleTo); void arithmeticOperatorBasicPositive() { absl::Duration d; d *= ConvertibleTo(); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast(ConvertibleTo()); d /= ConvertibleTo(); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d /= static_cast(ConvertibleTo()); d = ConvertibleTo() * d; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = static_cast(ConvertibleTo()) * d; d = d * ConvertibleTo(); // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = d * static_cast(ConvertibleTo()); d = d / ConvertibleTo(); // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = d / static_cast(ConvertibleTo()); d.operator*=(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:16: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d.operator*=(static_cast(ConvertibleTo())); d.operator/=(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:16: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d.operator/=(static_cast(ConvertibleTo())); d = operator*(ConvertibleTo(), d); // CHECK-MESSAGES: [[@LINE-1]]:17: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = operator*(static_cast(ConvertibleTo()), d); d = operator*(d, ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:20: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = operator*(d, static_cast(ConvertibleTo())); d = operator/(d, ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:20: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = operator/(d, static_cast(ConvertibleTo())); ConvertibleTo c; d *= (c + c) * c + c; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast((c + c) * c + c) d /= (c + c) * c + c; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d /= static_cast((c + c) * c + c) d = d * c * c; // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = d * static_cast(c) * static_cast(c) d = c * d * c; // CHECK-MESSAGES: [[@LINE-1]]:7: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = static_cast(c) * d * static_cast(c) d = d / c * c; // CHECK-MESSAGES: [[@LINE-1]]:11: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-MESSAGES: [[@LINE-2]]:15: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = d / static_cast(c) * static_cast(c) } void arithmeticOperatorBasicNegative() { absl::Duration d; d *= char{1}; d *= 1; d *= int64_t{1}; d *= 1.0f; d *= 1.0; d *= 1.0l; d /= char{1}; d /= 1; d /= int64_t{1}; d /= 1.0f; d /= 1.0; d /= 1.0l; d = d * char{1}; d = d * 1; d = d * int64_t{1}; d = d * 1.0f; d = d * 1.0; d = d * 1.0l; d = char{1} * d; d = 1 * d; d = int64_t{1} * d; d = 1.0f * d; d = 1.0 * d; d = 1.0l * d; d = d / char{1}; d = d / 1; d = d / int64_t{1}; d = d / 1.0f; d = d / 1.0; d = d / 1.0l; d *= static_cast(ConvertibleTo()); d *= (int)ConvertibleTo(); d *= int(ConvertibleTo()); d /= static_cast(ConvertibleTo()); d /= (int)ConvertibleTo(); d /= int(ConvertibleTo()); d = static_cast(ConvertibleTo()) * d; d = (int)ConvertibleTo() * d; d = int(ConvertibleTo()) * d; d = d * static_cast(ConvertibleTo()); d = d * (int)ConvertibleTo(); d = d * int(ConvertibleTo()); d = d / static_cast(ConvertibleTo()); d = d / (int)ConvertibleTo(); d = d / int(ConvertibleTo()); d *= 1 + ConvertibleTo(); d /= 1 + ConvertibleTo(); d = (1 + ConvertibleTo()) * d; d = d * (1 + ConvertibleTo()); d = d / (1 + ConvertibleTo()); } template void templateForOpsSpecialization(T) {} template <> void templateForOpsSpecialization(absl::Duration d) { d *= ConvertibleTo(); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast(ConvertibleTo()); } template void arithmeticNonTypeTemplateParamSpecialization() { absl::Duration d; d *= N; } template <> void arithmeticNonTypeTemplateParamSpecialization<5>() { absl::Duration d; d *= ConvertibleTo(); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast(ConvertibleTo()); } template void templateOpsFix() { absl::Duration d; d *= ConvertibleTo(); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast(ConvertibleTo()); } template void templateOpsWarnOnly(T t, U u) { t *= u; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead absl::Duration d; d *= u; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } template struct TemplateTypeOpsWarnOnly { void memberA(T t) { d *= t; // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } template void memberB(U u, V v) { u *= v; // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead d *= v; // CHECK-MESSAGES: [[@LINE-1]]:10: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } absl::Duration d; }; template void templateOpsInstantiationBeforeDefinition(T t, U u); void arithmeticOperatorsInTemplates() { templateForOpsSpecialization(5); templateForOpsSpecialization(absl::Duration()); arithmeticNonTypeTemplateParamSpecialization<1>(); arithmeticNonTypeTemplateParamSpecialization<5>(); templateOpsFix(); templateOpsWarnOnly(absl::Duration(), ConvertibleTo()); templateOpsInstantiationBeforeDefinition(absl::Duration(), ConvertibleTo()); TemplateTypeOpsWarnOnly> t; t.memberA(ConvertibleTo()); t.memberB(absl::Duration(), ConvertibleTo()); } template void templateOpsInstantiationBeforeDefinition(T t, U u) { t *= u; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead absl::Duration d; d *= u; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } #define FUNCTION_MACRO(x) x #define CONVERTIBLE_TMP ConvertibleTo() #define ONLY_WARN_INSIDE_MACRO_ARITHMETIC_OP d *= ConvertibleTo() #define T_OBJECT T() #define T_CALL_EXPR d *= T() template void arithmeticTemplateAndMacro() { absl::Duration d; d *= T_OBJECT; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead d *= CONVERTIBLE_TMP; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast(CONVERTIBLE_TMP); T_CALL_EXPR; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } #define TEMPLATE_MACRO(type) \ template void TemplateInMacro(T t) { \ type d; \ d *= t; \ } TEMPLATE_MACRO(absl::Duration) // CHECK-MESSAGES: [[@LINE-1]]:1: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead void arithmeticOperatorsInMacros() { absl::Duration d; d = FUNCTION_MACRO(d * ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:26: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d = FUNCTION_MACRO(d * static_cast(ConvertibleTo())); d *= FUNCTION_MACRO(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast(FUNCTION_MACRO(ConvertibleTo())); d *= CONVERTIBLE_TMP; // CHECK-MESSAGES: [[@LINE-1]]:8: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: d *= static_cast(CONVERTIBLE_TMP); ONLY_WARN_INSIDE_MACRO_ARITHMETIC_OP; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead arithmeticTemplateAndMacro>(); TemplateInMacro(ConvertibleTo()); } void factoryFunctionPositive() { // User defined conversion: (void)absl::Nanoseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(ConvertibleTo())); (void)absl::Microseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Microseconds(static_cast(ConvertibleTo())); (void)absl::Milliseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Milliseconds(static_cast(ConvertibleTo())); (void)absl::Seconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Seconds(static_cast(ConvertibleTo())); (void)absl::Minutes(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Minutes(static_cast(ConvertibleTo())); (void)absl::Hours(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Hours(static_cast(ConvertibleTo())); // User defined conversion to integral type, followed by built-in conversion: (void)absl::Nanoseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(ConvertibleTo())); (void)absl::Microseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Microseconds(static_cast(ConvertibleTo())); (void)absl::Milliseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Milliseconds(static_cast(ConvertibleTo())); (void)absl::Seconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Seconds(static_cast(ConvertibleTo())); (void)absl::Minutes(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Minutes(static_cast(ConvertibleTo())); (void)absl::Hours(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Hours(static_cast(ConvertibleTo())); // User defined conversion to floating point type, followed by built-in conversion: (void)absl::Nanoseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(ConvertibleTo())); (void)absl::Microseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Microseconds(static_cast(ConvertibleTo())); (void)absl::Milliseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:28: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Milliseconds(static_cast(ConvertibleTo())); (void)absl::Seconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Seconds(static_cast(ConvertibleTo())); (void)absl::Minutes(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:23: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Minutes(static_cast(ConvertibleTo())); (void)absl::Hours(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:21: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Hours(static_cast(ConvertibleTo())); } void factoryFunctionNegative() { (void)absl::Nanoseconds(char{1}); (void)absl::Nanoseconds(1); (void)absl::Nanoseconds(int64_t{1}); (void)absl::Nanoseconds(1.0f); (void)absl::Microseconds(char{1}); (void)absl::Microseconds(1); (void)absl::Microseconds(int64_t{1}); (void)absl::Microseconds(1.0f); (void)absl::Milliseconds(char{1}); (void)absl::Milliseconds(1); (void)absl::Milliseconds(int64_t{1}); (void)absl::Milliseconds(1.0f); (void)absl::Seconds(char{1}); (void)absl::Seconds(1); (void)absl::Seconds(int64_t{1}); (void)absl::Seconds(1.0f); (void)absl::Minutes(char{1}); (void)absl::Minutes(1); (void)absl::Minutes(int64_t{1}); (void)absl::Minutes(1.0f); (void)absl::Hours(char{1}); (void)absl::Hours(1); (void)absl::Hours(int64_t{1}); (void)absl::Hours(1.0f); (void)absl::Nanoseconds(static_cast(ConvertibleTo())); (void)absl::Microseconds(static_cast(ConvertibleTo())); (void)absl::Milliseconds(static_cast(ConvertibleTo())); (void)absl::Seconds(static_cast(ConvertibleTo())); (void)absl::Minutes(static_cast(ConvertibleTo())); (void)absl::Hours(static_cast(ConvertibleTo())); } template void templateForFactorySpecialization(T) {} template <> void templateForFactorySpecialization>(ConvertibleTo c) { (void)absl::Nanoseconds(c); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(c)); } template void factoryNonTypeTemplateParamSpecialization() { (void)absl::Nanoseconds(N); } template <> void factoryNonTypeTemplateParamSpecialization<5>() { (void)absl::Nanoseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(ConvertibleTo())); } template void templateFactoryFix() { (void)absl::Nanoseconds(ConvertibleTo()); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(ConvertibleTo())); } template void templateFactoryWarnOnly(T t) { (void)absl::Nanoseconds(t); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } template void templateFactoryInstantiationBeforeDefinition(T t); template struct TemplateTypeFactoryWarnOnly { void memberA(T t) { (void)absl::Nanoseconds(t); // CHECK-MESSAGES: [[@LINE-1]]:29: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } template void memberB(U u) { (void)absl::Nanoseconds(u); // CHECK-MESSAGES: [[@LINE-1]]:29: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } }; void factoryInTemplates() { templateForFactorySpecialization(5); templateForFactorySpecialization(ConvertibleTo()); factoryNonTypeTemplateParamSpecialization<1>(); factoryNonTypeTemplateParamSpecialization<5>(); templateFactoryFix(); templateFactoryWarnOnly(ConvertibleTo()); templateFactoryInstantiationBeforeDefinition(ConvertibleTo()); TemplateTypeFactoryWarnOnly> t; t.memberA(ConvertibleTo()); t.memberB(ConvertibleTo()); } template void templateFactoryInstantiationBeforeDefinition(T t) { (void)absl::Nanoseconds(t); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } #define ONLY_WARN_INSIDE_MACRO_FACTORY \ (void)absl::Nanoseconds(ConvertibleTo()) #define T_CALL_FACTORTY_INSIDE_MACRO (void)absl::Nanoseconds(T()) template void factoryTemplateAndMacro() { (void)absl::Nanoseconds(T_OBJECT); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead (void)absl::Nanoseconds(CONVERTIBLE_TMP); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(CONVERTIBLE_TMP)) T_CALL_FACTORTY_INSIDE_MACRO; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead } #define TEMPLATE_FACTORY_MACRO(factory) \ template void TemplateFactoryInMacro(T t) { (void)factory(t); } TEMPLATE_FACTORY_MACRO(absl::Nanoseconds) // CHECK-MESSAGES: [[@LINE-1]]:1: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead void factoryInMacros() { (void)absl::Nanoseconds(FUNCTION_MACRO(ConvertibleTo())); // CHECK-MESSAGES: [[@LINE-1]]:42: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(FUNCTION_MACRO(ConvertibleTo()))); (void)absl::Nanoseconds(CONVERTIBLE_TMP); // CHECK-MESSAGES: [[@LINE-1]]:27: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead // CHECK-FIXES: (void)absl::Nanoseconds(static_cast(CONVERTIBLE_TMP)) ONLY_WARN_INSIDE_MACRO_FACTORY; // CHECK-MESSAGES: [[@LINE-1]]:3: warning: implicit conversion to 'int64_t' is deprecated in this context; use an explicit cast instead factoryTemplateAndMacro>(); TemplateFactoryInMacro(ConvertibleTo()); } // This is a reduced test-case for PR39949 and manifested in this check. namespace std { template _Tp declval(); template struct __res { template static decltype(declval<_Functor>()(_Args()...)) _S_test(int); template static void _S_test(...); typedef decltype(_S_test<_ArgTypes...>(0)) type; }; template struct function; template struct function { template ::type> function(_Functor) {} }; } // namespace std typedef std::function F; F foo() { return F([] {}); }