1 // RUN: %check_clang_tidy -std=c++11-or-later %s abseil-time-subtraction %t -- -- -I %S/Inputs
2 
3 #include "absl/time/time.h"
4 
5 void g(absl::Duration d);
6 
f()7 void f() {
8   absl::Time t;
9   int x, y;
10   absl::Duration d;
11 
12   d = absl::Hours(absl::ToUnixHours(t) - x);
13   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
14   // CHECK-FIXES: d = (t - absl::FromUnixHours(x));
15   d = absl::Minutes(absl::ToUnixMinutes(t) - x);
16   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
17   // CHECK-FIXES: d = (t - absl::FromUnixMinutes(x));
18   d = absl::Seconds(absl::ToUnixSeconds(t) - x);
19   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
20   // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x));
21   d = absl::Milliseconds(absl::ToUnixMillis(t) - x);
22   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
23   // CHECK-FIXES: d = (t - absl::FromUnixMillis(x));
24   d = absl::Microseconds(absl::ToUnixMicros(t) - x);
25   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
26   // CHECK-FIXES: d = (t - absl::FromUnixMicros(x));
27   d = absl::Nanoseconds(absl::ToUnixNanos(t) - x);
28   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
29   // CHECK-FIXES: d = (t - absl::FromUnixNanos(x));
30 
31   y = x - absl::ToUnixHours(t);
32   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
33   // CHECK-FIXES: y = absl::ToInt64Hours(absl::FromUnixHours(x) - t);
34   y = x - absl::ToUnixMinutes(t);
35   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
36   // CHECK-FIXES: y = absl::ToInt64Minutes(absl::FromUnixMinutes(x) - t);
37   y = x - absl::ToUnixSeconds(t);
38   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
39   // CHECK-FIXES: y = absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t);
40   y = x - absl::ToUnixMillis(t);
41   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
42   // CHECK-FIXES: y = absl::ToInt64Milliseconds(absl::FromUnixMillis(x) - t);
43   y = x - absl::ToUnixMicros(t);
44   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
45   // CHECK-FIXES: y = absl::ToInt64Microseconds(absl::FromUnixMicros(x) - t);
46   y = x - absl::ToUnixNanos(t);
47   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
48   // CHECK-FIXES: y = absl::ToInt64Nanoseconds(absl::FromUnixNanos(x) - t);
49 
50   // Check parenthesis placement
51   d = 5 * absl::Seconds(absl::ToUnixSeconds(t) - x);
52   // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform subtraction in the time domain [abseil-time-subtraction]
53   // CHECK-FIXES: d = 5 * (t - absl::FromUnixSeconds(x));
54   d = absl::Seconds(absl::ToUnixSeconds(t) - x) / 5;
55   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
56   // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x)) / 5;
57 
58   // No extra parens around arguments
59   g(absl::Seconds(absl::ToUnixSeconds(t) - x));
60   // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
61   // CHECK-FIXES: g(t - absl::FromUnixSeconds(x));
62   g(absl::Seconds(x - absl::ToUnixSeconds(t)));
63   // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
64   // CHECK-FIXES: g(absl::FromUnixSeconds(x) - t);
65 
66   // More complex subexpressions
67   d = absl::Hours(absl::ToUnixHours(t) - 5 * x);
68   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
69   // CHECK-FIXES: d = (t - absl::FromUnixHours(5 * x));
70 
71   // These should not trigger; they are likely bugs
72   d = absl::Milliseconds(absl::ToUnixSeconds(t) - x);
73   d = absl::Seconds(absl::ToUnixMicros(t) - x);
74 
75   // Various macro scenarios
76 #define SUB(z, t1) z - absl::ToUnixSeconds(t1)
77   y = SUB(x, t);
78 #undef SUB
79 
80 #define MILLIS(t1) absl::ToUnixMillis(t1)
81   y = x - MILLIS(t);
82 #undef MILLIS
83 
84 #define HOURS(z) absl::Hours(z)
85   d = HOURS(absl::ToUnixHours(t) - x);
86 #undef HOURS
87 
88   // This should match the expression inside the macro invocation.
89 #define SECONDS(z) absl::Seconds(z)
90   d = SECONDS(x - absl::ToUnixSeconds(t));
91   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: perform subtraction in the time domain [abseil-time-subtraction]
92   // CHECK-FIXES: SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t))
93 #undef SECONDS
94 }
95 
96 template<typename T>
func(absl::Time t,T x)97 void func(absl::Time t, T x) {
98   absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) - x);
99   // CHECK-MESSAGES: [[@LINE-1]]:22: warning: perform subtraction in the time domain [abseil-time-subtraction]
100   // CHECK-FIXES: absl::Duration d = t - absl::FromUnixSeconds(x);
101 }
102 
g()103 void g() {
104   func(absl::Now(), 5);
105 }
106 
parens_in_return()107 absl::Duration parens_in_return() {
108   absl::Time t;
109   int x;
110 
111   return absl::Seconds(absl::ToUnixSeconds(t) - x);
112   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
113   // CHECK-FIXES: return t - absl::FromUnixSeconds(x);
114   return absl::Seconds(x - absl::ToUnixSeconds(t));
115   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
116   // CHECK-FIXES: return absl::FromUnixSeconds(x) - t;
117 }
118