summaryrefslogtreecommitdiffstats
path: root/test/clang-tidy/abseil-time-subtraction.cpp
blob: 6f5d4b45af9760ed6fb6b713c5ec861514c79347 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// RUN: %check_clang_tidy %s abseil-time-subtraction %t -- -- -I%S/Inputs

#include "absl/time/time.h"

void g(absl::Duration d);

void f() {
  absl::Time t;
  int x, y;
  absl::Duration d;

  d = absl::Hours(absl::ToUnixHours(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixHours(x));
  d = absl::Minutes(absl::ToUnixMinutes(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixMinutes(x));
  d = absl::Seconds(absl::ToUnixSeconds(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x));
  d = absl::Milliseconds(absl::ToUnixMillis(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixMillis(x));
  d = absl::Microseconds(absl::ToUnixMicros(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixMicros(x));
  d = absl::Nanoseconds(absl::ToUnixNanos(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixNanos(x));

  y = x - absl::ToUnixHours(t);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: y = absl::ToInt64Hours(absl::FromUnixHours(x) - t);
  y = x - absl::ToUnixMinutes(t);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: y = absl::ToInt64Minutes(absl::FromUnixMinutes(x) - t);
  y = x - absl::ToUnixSeconds(t);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: y = absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t);
  y = x - absl::ToUnixMillis(t);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: y = absl::ToInt64Milliseconds(absl::FromUnixMillis(x) - t);
  y = x - absl::ToUnixMicros(t);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: y = absl::ToInt64Microseconds(absl::FromUnixMicros(x) - t);
  y = x - absl::ToUnixNanos(t);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: y = absl::ToInt64Nanoseconds(absl::FromUnixNanos(x) - t);

  // Check parenthesis placement
  d = 5 * absl::Seconds(absl::ToUnixSeconds(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = 5 * (t - absl::FromUnixSeconds(x));
  d = absl::Seconds(absl::ToUnixSeconds(t) - x) / 5;
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x)) / 5;

  // No extra parens around arguments
  g(absl::Seconds(absl::ToUnixSeconds(t) - x));
  // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: g(t - absl::FromUnixSeconds(x));
  g(absl::Seconds(x - absl::ToUnixSeconds(t)));
  // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: g(absl::FromUnixSeconds(x) - t);

  // More complex subexpressions
  d = absl::Hours(absl::ToUnixHours(t) - 5 * x);
  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: d = (t - absl::FromUnixHours(5 * x));

  // These should not trigger; they are likely bugs
  d = absl::Milliseconds(absl::ToUnixSeconds(t) - x);
  d = absl::Seconds(absl::ToUnixMicros(t) - x);

  // Various macro scenarios
#define SUB(z, t1) z - absl::ToUnixSeconds(t1)
  y = SUB(x, t);
#undef SUB

#define MILLIS(t1) absl::ToUnixMillis(t1)
  y = x - MILLIS(t);
#undef MILLIS

#define HOURS(z) absl::Hours(z)
  d = HOURS(absl::ToUnixHours(t) - x);
#undef HOURS

  // This should match the expression inside the macro invocation.
#define SECONDS(z) absl::Seconds(z)
  d = SECONDS(x - absl::ToUnixSeconds(t));
  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t))
#undef SECONDS
}

template<typename T>
void func(absl::Time t, T x) {
  absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: absl::Duration d = t - absl::FromUnixSeconds(x);
}

void g() {
  func(absl::Now(), 5);
}

absl::Duration parens_in_return() {
  absl::Time t;
  int x;

  return absl::Seconds(absl::ToUnixSeconds(t) - x);
  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: return t - absl::FromUnixSeconds(x);
  return absl::Seconds(x - absl::ToUnixSeconds(t));
  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction]
  // CHECK-FIXES: return absl::FromUnixSeconds(x) - t;
}