summaryrefslogtreecommitdiff
path: root/clang-tools-extra/test
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2018-12-07 20:03:03 +0000
committerEric Fiselier <eric@efcs.ca>2018-12-07 20:03:03 +0000
commita569dd5d002059c57d94744cf0d8bc10c06b893b (patch)
tree3beff003a20b906610fcb160f94fb51c3ee09e07 /clang-tools-extra/test
parent3cbe6e69d3ffa7155ebfc1ea9b157aff33157cd3 (diff)
[clang-tidy]: Abseil: new check 'abseil-upgrade-duration-conversions'
Patch by Alex Strelnikov. Reviewed as D53830 Introduce a new check to upgrade user code based on upcoming API breaking changes to absl::Duration. The check finds calls to arithmetic operators and factory functions for absl::Duration that rely on an implicit user defined conversion to int64_t. These cases will no longer compile after proposed changes are released. Suggested fixes explicitly cast the argument int64_t.
Diffstat (limited to 'clang-tools-extra/test')
-rw-r--r--clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp473
1 files changed, 473 insertions, 0 deletions
diff --git a/clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp b/clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
new file mode 100644
index 00000000000..3ac113c7902
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/abseil-upgrade-duration-conversions.cpp
@@ -0,0 +1,473 @@
+// RUN: %check_clang_tidy %s abseil-upgrade-duration-conversions %t
+
+using int64_t = long long;
+
+// Partial implementation of relevant APIs from
+// https://github.com/abseil/abseil-cpp/blob/master/absl/time/time.h
+namespace absl {
+
+class Duration {
+public:
+ Duration &operator*=(int64_t r);
+ Duration &operator*=(float r);
+ Duration &operator*=(double r);
+ template <typename T> Duration &operator*=(T r);
+
+ Duration &operator/=(int64_t r);
+ Duration &operator/=(float r);
+ Duration &operator/=(double r);
+ template <typename T> Duration &operator/=(T r);
+};
+
+template <typename T> Duration operator*(Duration lhs, T rhs);
+template <typename T> Duration operator*(T lhs, Duration rhs);
+template <typename T> Duration operator/(Duration lhs, T rhs);
+
+constexpr Duration Nanoseconds(int64_t n);
+constexpr Duration Microseconds(int64_t n);
+constexpr Duration Milliseconds(int64_t n);
+constexpr Duration Seconds(int64_t n);
+constexpr Duration Minutes(int64_t n);
+constexpr Duration Hours(int64_t n);
+
+template <typename T> struct EnableIfFloatImpl {};
+template <> struct EnableIfFloatImpl<float> { typedef int Type; };
+template <> struct EnableIfFloatImpl<double> { typedef int Type; };
+template <> struct EnableIfFloatImpl<long double> { typedef int Type; };
+template <typename T> using EnableIfFloat = typename EnableIfFloatImpl<T>::Type;
+
+template <typename T, EnableIfFloat<T> = 0> Duration Nanoseconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Microseconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Milliseconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Seconds(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Minutes(T n);
+template <typename T, EnableIfFloat<T> = 0> Duration Hours(T n);
+
+} // namespace absl
+
+template <typename T> struct ConvertibleTo {
+ operator T() const;
+};
+
+template <typename T>
+ConvertibleTo<T> operator+(ConvertibleTo<T>, ConvertibleTo<T>);
+
+template <typename T>
+ConvertibleTo<T> operator*(ConvertibleTo<T>, ConvertibleTo<T>);
+
+void arithmeticOperatorBasicPositive() {
+ absl::Duration d;
+ d *= ConvertibleTo<int64_t>();
+ // 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<int64_t>(ConvertibleTo<int64_t>());
+ d /= ConvertibleTo<int64_t>();
+ // 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<int64_t>(ConvertibleTo<int64_t>());
+ d = ConvertibleTo<int64_t>() * 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<int64_t>(ConvertibleTo<int64_t>()) * d;
+ d = d * ConvertibleTo<int64_t>();
+ // 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<int64_t>(ConvertibleTo<int64_t>());
+ d = d / ConvertibleTo<int64_t>();
+ // 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<int64_t>(ConvertibleTo<int64_t>());
+ d.operator*=(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ d.operator/=(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ d = operator*(ConvertibleTo<int64_t>(), 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<int64_t>(ConvertibleTo<int64_t>()), d);
+ d = operator*(d, ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ d = operator/(d, ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ ConvertibleTo<int64_t> 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<int64_t>((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<int64_t>((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<int64_t>(c) * static_cast<int64_t>(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<int64_t>(c) * d * static_cast<int64_t>(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<int64_t>(c) * static_cast<int64_t>(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<int>(ConvertibleTo<int>());
+ d *= (int)ConvertibleTo<int>();
+ d *= int(ConvertibleTo<int>());
+ d /= static_cast<int>(ConvertibleTo<int>());
+ d /= (int)ConvertibleTo<int>();
+ d /= int(ConvertibleTo<int>());
+ d = static_cast<int>(ConvertibleTo<int>()) * d;
+ d = (int)ConvertibleTo<int>() * d;
+ d = int(ConvertibleTo<int>()) * d;
+ d = d * static_cast<int>(ConvertibleTo<int>());
+ d = d * (int)ConvertibleTo<int>();
+ d = d * int(ConvertibleTo<int>());
+ d = d / static_cast<int>(ConvertibleTo<int>());
+ d = d / (int)ConvertibleTo<int>();
+ d = d / int(ConvertibleTo<int>());
+
+ d *= 1 + ConvertibleTo<int>();
+ d /= 1 + ConvertibleTo<int>();
+ d = (1 + ConvertibleTo<int>()) * d;
+ d = d * (1 + ConvertibleTo<int>());
+ d = d / (1 + ConvertibleTo<int>());
+}
+
+template <typename T> void templateForOpsSpecialization(T) {}
+template <>
+void templateForOpsSpecialization<absl::Duration>(absl::Duration d) {
+ d *= ConvertibleTo<int64_t>();
+ // 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<int64_t>(ConvertibleTo<int64_t>());
+}
+
+template <int N> void arithmeticNonTypeTemplateParamSpecialization() {
+ absl::Duration d;
+ d *= N;
+}
+
+template <> void arithmeticNonTypeTemplateParamSpecialization<5>() {
+ absl::Duration d;
+ d *= ConvertibleTo<int>();
+ // 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<int64_t>(ConvertibleTo<int>());
+}
+
+template <typename T> void templateOpsFix() {
+ absl::Duration d;
+ d *= ConvertibleTo<int64_t>();
+ // 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<int64_t>(ConvertibleTo<int64_t>());
+}
+
+template <typename T, typename U> 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 <typename T> 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 <typename U, typename V> 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 <typename T, typename U>
+void templateOpsInstantiationBeforeDefinition(T t, U u);
+
+void arithmeticOperatorsInTemplates() {
+ templateForOpsSpecialization(5);
+ templateForOpsSpecialization(absl::Duration());
+ arithmeticNonTypeTemplateParamSpecialization<1>();
+ arithmeticNonTypeTemplateParamSpecialization<5>();
+ templateOpsFix<int>();
+ templateOpsWarnOnly(absl::Duration(), ConvertibleTo<int>());
+ templateOpsInstantiationBeforeDefinition(absl::Duration(),
+ ConvertibleTo<int>());
+ TemplateTypeOpsWarnOnly<ConvertibleTo<int>> t;
+ t.memberA(ConvertibleTo<int>());
+ t.memberB(absl::Duration(), ConvertibleTo<int>());
+}
+
+template <typename T, typename U>
+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<int>()
+#define ONLY_WARN_INSIDE_MACRO_ARITHMETIC_OP d *= ConvertibleTo<int>()
+
+#define T_OBJECT T()
+#define T_CALL_EXPR d *= T()
+
+template <typename T> 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<int64_t>(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 <typename T> 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<int>());
+ // 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<int64_t>(ConvertibleTo<int>()));
+ d *= FUNCTION_MACRO(ConvertibleTo<int>());
+ // 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<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>()));
+ 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<int64_t>(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<ConvertibleTo<int>>();
+ TemplateInMacro(ConvertibleTo<int>());
+}
+
+void factoryFunctionPositive() {
+ // User defined conversion:
+ (void)absl::Nanoseconds(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Microseconds(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Milliseconds(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Seconds(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Minutes(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+ (void)absl::Hours(ConvertibleTo<int64_t>());
+ // 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<int64_t>(ConvertibleTo<int64_t>()));
+
+ // User defined conversion to integral type, followed by built-in conversion:
+ (void)absl::Nanoseconds(ConvertibleTo<char>());
+ // 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<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Microseconds(ConvertibleTo<char>());
+ // 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<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Milliseconds(ConvertibleTo<char>());
+ // 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<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Seconds(ConvertibleTo<char>());
+ // 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<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Minutes(ConvertibleTo<char>());
+ // 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<int64_t>(ConvertibleTo<char>()));
+ (void)absl::Hours(ConvertibleTo<char>());
+ // 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<int64_t>(ConvertibleTo<char>()));
+
+ // User defined conversion to floating point type, followed by built-in conversion:
+ (void)absl::Nanoseconds(ConvertibleTo<float>());
+ // 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<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Microseconds(ConvertibleTo<float>());
+ // 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<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Milliseconds(ConvertibleTo<float>());
+ // 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<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Seconds(ConvertibleTo<float>());
+ // 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<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Minutes(ConvertibleTo<float>());
+ // 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<int64_t>(ConvertibleTo<float>()));
+ (void)absl::Hours(ConvertibleTo<float>());
+ // 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<int64_t>(ConvertibleTo<float>()));
+}
+
+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<int>(ConvertibleTo<int>()));
+ (void)absl::Microseconds(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Milliseconds(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Seconds(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Minutes(static_cast<int>(ConvertibleTo<int>()));
+ (void)absl::Hours(static_cast<int>(ConvertibleTo<int>()));
+}
+
+template <typename T> void templateForFactorySpecialization(T) {}
+template <> void templateForFactorySpecialization<ConvertibleTo<int>>(ConvertibleTo<int> 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<int64_t>(c));
+}
+
+template <int N> void factoryNonTypeTemplateParamSpecialization() {
+ (void)absl::Nanoseconds(N);
+}
+
+template <> void factoryNonTypeTemplateParamSpecialization<5>() {
+ (void)absl::Nanoseconds(ConvertibleTo<int>());
+ // 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<int64_t>(ConvertibleTo<int>()));
+}
+
+template <typename T> void templateFactoryFix() {
+ (void)absl::Nanoseconds(ConvertibleTo<int>());
+ // 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<int64_t>(ConvertibleTo<int>()));
+}
+
+template <typename T> 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 <typename T> void templateFactoryInstantiationBeforeDefinition(T t);
+
+template <typename T> 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 <typename U> 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<int>());
+ factoryNonTypeTemplateParamSpecialization<1>();
+ factoryNonTypeTemplateParamSpecialization<5>();
+ templateFactoryFix<int>();
+ templateFactoryWarnOnly(ConvertibleTo<int>());
+ templateFactoryInstantiationBeforeDefinition(ConvertibleTo<int>());
+ TemplateTypeFactoryWarnOnly<ConvertibleTo<int>> t;
+ t.memberA(ConvertibleTo<int>());
+ t.memberB(ConvertibleTo<int>());
+}
+
+template <typename T> 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<int>())
+#define T_CALL_FACTORTY_INSIDE_MACRO (void)absl::Nanoseconds(T())
+
+template <typename T> 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<int64_t>(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 <typename T> 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<int>()));
+ // 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<int64_t>(FUNCTION_MACRO(ConvertibleTo<int>())));
+ (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<int64_t>(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<ConvertibleTo<int>>();
+ TemplateFactoryInMacro(ConvertibleTo<int>());
+}