1 // RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
2 
3 #include "absl/time/time.h"
4 
f()5 void f() {
6   absl::Time t;
7   int i;
8 
9   i = absl::ToUnixHours(t) + 5;
10   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
11   // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
12   i = absl::ToUnixMinutes(t) + 5;
13   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
14   // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
15   i = absl::ToUnixSeconds(t) + 5;
16   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
17   // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
18   i = absl::ToUnixMillis(t) + 5;
19   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
20   // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
21   i = absl::ToUnixMicros(t) + 5;
22   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
23   // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
24   i = absl::ToUnixNanos(t) + 5;
25   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
26   // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
27 
28   i = 3 + absl::ToUnixHours(t);
29   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
30   // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
31   i = 3 + absl::ToUnixMinutes(t);
32   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
33   // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
34   i = 3 + absl::ToUnixSeconds(t);
35   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
36   // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
37   i = 3 + absl::ToUnixMillis(t);
38   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
39   // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
40   i = 3 + absl::ToUnixMicros(t);
41   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
42   // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
43   i = 3 + absl::ToUnixNanos(t);
44   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
45   // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
46 
47   // Undoing inverse conversions
48   i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
49   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
50   // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
51 
52   // Parens
53   i = 3 + (absl::ToUnixHours(t));
54   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
55   // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
56 
57   // Float folding
58   i = absl::ToUnixSeconds(t) + 5.0;
59   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
60   // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
61 
62   // We can rewrite the argument of the duration conversion
63 #define THIRTY absl::FromUnixSeconds(30)
64   i = absl::ToUnixSeconds(THIRTY) + 1;
65   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
66   // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
67 #undef THIRTY
68 
69   // Some other contexts
70   if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
71   // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
72   // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
73 
74   // These should not match
75   i = 5 + 6;
76   i = absl::ToUnixSeconds(t) - 1.0;
77   i = absl::ToUnixSeconds(t) * 1.0;
78   i = absl::ToUnixSeconds(t) / 1.0;
79   i += absl::ToInt64Microseconds(absl::Seconds(1));
80 
81 #define PLUS_FIVE(z) absl::ToUnixSeconds(z) + 5
82   i = PLUS_FIVE(t);
83 #undef PLUS_FIVE
84 }
85 
86 // Within a templated function
87 template<typename T>
foo(absl::Time t)88 void foo(absl::Time t) {
89   int i = absl::ToUnixNanos(t) + T{};
90   // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform addition in the duration domain [abseil-duration-addition]
91   // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(T{}))
92 }
93 
g()94 void g() {
95   absl::Time t;
96   foo<int>(t);
97   foo<double>(t);
98 }
99