[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-28 Thread Hyrum Wright via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL352362: [clang-tidy] Add the abseil-duration-addition check 
(authored by hwright, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D57185?vs=183583=183840#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185

Files:
  clang-tools-extra/trunk/clang-tidy/abseil/AbseilTidyModule.cpp
  clang-tools-extra/trunk/clang-tidy/abseil/CMakeLists.txt
  clang-tools-extra/trunk/clang-tidy/abseil/DurationAdditionCheck.cpp
  clang-tools-extra/trunk/clang-tidy/abseil/DurationAdditionCheck.h
  clang-tools-extra/trunk/clang-tidy/abseil/DurationRewriter.cpp
  clang-tools-extra/trunk/clang-tidy/abseil/DurationRewriter.h
  clang-tools-extra/trunk/docs/ReleaseNotes.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/abseil-duration-addition.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
  clang-tools-extra/trunk/test/clang-tidy/Inputs/absl/time/time.h
  clang-tools-extra/trunk/test/clang-tidy/abseil-duration-addition.cpp

Index: clang-tools-extra/trunk/clang-tidy/abseil/DurationRewriter.cpp
===
--- clang-tools-extra/trunk/clang-tidy/abseil/DurationRewriter.cpp
+++ clang-tools-extra/trunk/clang-tidy/abseil/DurationRewriter.cpp
@@ -103,6 +103,25 @@
   llvm_unreachable("unknown scaling factor");
 }
 
+/// Returns the Time factory function name for a given `Scale`.
+llvm::StringRef getTimeFactoryForScale(DurationScale scale) {
+  switch (scale) {
+  case DurationScale::Hours:
+return "absl::ToUnixHours";
+  case DurationScale::Minutes:
+return "absl::ToUnixMinutes";
+  case DurationScale::Seconds:
+return "absl::ToUnixSeconds";
+  case DurationScale::Milliseconds:
+return "absl::ToUnixMillis";
+  case DurationScale::Microseconds:
+return "absl::ToUnixMicros";
+  case DurationScale::Nanoseconds:
+return "absl::ToUnixNanos";
+  }
+  llvm_unreachable("unknown scaling factor");
+}
+
 /// Returns `true` if `Node` is a value which evaluates to a literal `0`.
 bool IsLiteralZero(const MatchFinder::MatchResult , const Expr ) {
   auto ZeroMatcher =
@@ -197,6 +216,22 @@
   return ScaleIter->second;
 }
 
+llvm::Optional getScaleForTimeInverse(llvm::StringRef Name) {
+  static const llvm::StringMap ScaleMap(
+  {{"ToUnixHours", DurationScale::Hours},
+   {"ToUnixMinutes", DurationScale::Minutes},
+   {"ToUnixSeconds", DurationScale::Seconds},
+   {"ToUnixMillis", DurationScale::Milliseconds},
+   {"ToUnixMicros", DurationScale::Microseconds},
+   {"ToUnixNanos", DurationScale::Nanoseconds}});
+
+  auto ScaleIter = ScaleMap.find(std::string(Name));
+  if (ScaleIter == ScaleMap.end())
+return llvm::None;
+
+  return ScaleIter->second;
+}
+
 std::string rewriteExprFromNumberToDuration(
 const ast_matchers::MatchFinder::MatchResult , DurationScale Scale,
 const Expr *Node) {
Index: clang-tools-extra/trunk/clang-tidy/abseil/AbseilTidyModule.cpp
===
--- clang-tools-extra/trunk/clang-tidy/abseil/AbseilTidyModule.cpp
+++ clang-tools-extra/trunk/clang-tidy/abseil/AbseilTidyModule.cpp
@@ -9,6 +9,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "DurationAdditionCheck.h"
 #include "DurationComparisonCheck.h"
 #include "DurationConversionCastCheck.h"
 #include "DurationDivisionCheck.h"
@@ -30,6 +31,8 @@
 class AbseilModule : public ClangTidyModule {
 public:
   void addCheckFactories(ClangTidyCheckFactories ) override {
+CheckFactories.registerCheck(
+"abseil-duration-addition");
 CheckFactories.registerCheck(
 "abseil-duration-comparison");
 CheckFactories.registerCheck(
Index: clang-tools-extra/trunk/clang-tidy/abseil/DurationAdditionCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/abseil/DurationAdditionCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/abseil/DurationAdditionCheck.cpp
@@ -0,0 +1,73 @@
+//===--- DurationAdditionCheck.cpp - clang-tidy===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "DurationAdditionCheck.h"
+#include "DurationRewriter.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/FixIt.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  

[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-28 Thread Jonas Toth via Phabricator via cfe-commits
JonasToth accepted this revision.
JonasToth added a comment.
This revision is now accepted and ready to land.

LGTM


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Hyrum Wright via Phabricator via cfe-commits
hwright updated this revision to Diff 183583.
hwright marked an inline comment as done.
hwright added a comment.

Add another test


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185

Files:
  clang-tidy/abseil/AbseilTidyModule.cpp
  clang-tidy/abseil/CMakeLists.txt
  clang-tidy/abseil/DurationAdditionCheck.cpp
  clang-tidy/abseil/DurationAdditionCheck.h
  clang-tidy/abseil/DurationRewriter.cpp
  clang-tidy/abseil/DurationRewriter.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/abseil-duration-addition.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/Inputs/absl/time/time.h
  test/clang-tidy/abseil-duration-addition.cpp

Index: test/clang-tidy/abseil-duration-addition.cpp
===
--- /dev/null
+++ test/clang-tidy/abseil-duration-addition.cpp
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  absl::Time t;
+  int i;
+
+  i = absl::ToUnixHours(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
+  i = absl::ToUnixMinutes(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
+  i = absl::ToUnixSeconds(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+  i = absl::ToUnixMillis(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
+  i = absl::ToUnixMicros(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
+  i = absl::ToUnixNanos(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
+
+  i = 3 + absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+  i = 3 + absl::ToUnixMinutes(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
+  i = 3 + absl::ToUnixSeconds(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
+  i = 3 + absl::ToUnixMillis(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
+  i = 3 + absl::ToUnixMicros(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
+  i = 3 + absl::ToUnixNanos(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
+
+  // Undoing inverse conversions
+  i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
+
+  // Parens
+  i = 3 + (absl::ToUnixHours(t));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+
+  // Float folding
+  i = absl::ToUnixSeconds(t) + 5.0;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+
+  // We can rewrite the argument of the duration conversion
+#define THIRTY absl::FromUnixSeconds(30)
+  i = absl::ToUnixSeconds(THIRTY) + 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
+#undef THIRTY
+
+  // Some other contexts
+  if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
+
+  // These should not match
+  i = 5 + 6;
+  i = absl::ToUnixSeconds(t) - 1.0;
+  i = absl::ToUnixSeconds(t) * 1.0;
+  i = 

[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Jonas Toth via Phabricator via cfe-commits
JonasToth added inline comments.



Comment at: test/clang-tidy/abseil-duration-addition.cpp:84
+#undef PLUS_FIVE
+}

hwright wrote:
> JonasToth wrote:
> > a view template test-cases would be good to have.
> I'm not sure I know that terminology; do you have an example?
```
template
void foo(absl::Time t) {
  int i = absl::ToUnixNanos(t) + T{};
}
foo(t);
foo(t);
```


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Hyrum Wright via Phabricator via cfe-commits
hwright marked 2 inline comments as done.
hwright added inline comments.



Comment at: test/clang-tidy/abseil-duration-addition.cpp:84
+#undef PLUS_FIVE
+}

JonasToth wrote:
> a view template test-cases would be good to have.
I'm not sure I know that terminology; do you have an example?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Jonas Toth via Phabricator via cfe-commits
JonasToth added inline comments.



Comment at: clang-tidy/abseil/DurationAdditionCheck.cpp:22
+void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  binaryOperator(hasOperatorName("+"),

hwright wrote:
> JonasToth wrote:
> > This whole file is structurally similar to the 
> > `DurationSubtractionCheck.cpp` equivalent (which is expected :)), maybe 
> > some parts could be refactored out?
> > Will there be a check for duration scaling or the like?
> I think that most of it already has been factored out (e.g., 
> `rewriteExprFromNumberToDuration` and `getScaleForTimeInverse`, etc) . The 
> actual meat here is pretty light: the matcher, and then the diagnostic 
> generation.
> 
> A scaling change may also follow.  Our experience has been that scaling isn't 
> quite straight forward, as the scaling factor may have semantic meaning which 
> changes the result, but which isn't captured by the type system.  Probably 
> not a design discussion to have here, but suffice it to say that I don't know 
> if this is yet settled.
Your right, there is not too much to gain. Only if there are more checks coming 
with the same structure it makes sense to think again.



Comment at: test/clang-tidy/abseil-duration-addition.cpp:84
+#undef PLUS_FIVE
+}

a view template test-cases would be good to have.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Hyrum Wright via Phabricator via cfe-commits
hwright added inline comments.



Comment at: clang-tidy/abseil/DurationAdditionCheck.cpp:22
+void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  binaryOperator(hasOperatorName("+"),

JonasToth wrote:
> This whole file is structurally similar to the `DurationSubtractionCheck.cpp` 
> equivalent (which is expected :)), maybe some parts could be refactored out?
> Will there be a check for duration scaling or the like?
I think that most of it already has been factored out (e.g., 
`rewriteExprFromNumberToDuration` and `getScaleForTimeInverse`, etc) . The 
actual meat here is pretty light: the matcher, and then the diagnostic 
generation.

A scaling change may also follow.  Our experience has been that scaling isn't 
quite straight forward, as the scaling factor may have semantic meaning which 
changes the result, but which isn't captured by the type system.  Probably not 
a design discussion to have here, but suffice it to say that I don't know if 
this is yet settled.



Comment at: clang-tidy/abseil/DurationAdditionCheck.cpp:50
+diag(Binop->getBeginLoc(), "perform addition in the duration domain")
+<< FixItHint::CreateReplacement(
+   Binop->getSourceRange(),

JonasToth wrote:
> The only difference between the two `diag` seems to be the `FixItHint`. I 
> would rather refactor the diag out of the `if`.
This doesn't really de-dupe very much, since the bulk of the work here is 
creating the `FixItHint`.  Done.



Comment at: clang-tidy/abseil/DurationAdditionCheck.cpp:60
+  } else {
+assert(Call == Binop->getRHS()->IgnoreImpCast() && "Call should be found 
on the RHS");
+diag(Binop->getBeginLoc(), "perform addition in the duration domain")

JonasToth wrote:
> What happens with paren-casts, are they ignored as well? (See one comment in 
> the test-cases)
Now they are.



Comment at: test/clang-tidy/abseil-duration-addition.cpp:28
+
+  i = 3 + absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration 
domain [abseil-duration-addition]

JonasToth wrote:
> Call is on the right side, what happens for `3 + (abs::ToUnixHours(t));`
Added this test, and updated to ignore paren casts.



Comment at: test/clang-tidy/abseil-duration-addition.cpp:48
+  // Undoing inverse conversions
+  i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration 
domain [abseil-duration-addition]

JonasToth wrote:
> Is something like this
> ```
> i += absl::ToInt64MicroSeconds(absl::Seconds(1));
> ```
> possible (syntactically and semantically)?
> The compound operators are currently not covered by this (and the 
> subtraction-check), but in this case it looks like a possible use-case.
Semantically, this is possible, but wouldn't fall under this transform, since 
it would require changing the type of `i`.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Hyrum Wright via Phabricator via cfe-commits
hwright updated this revision to Diff 183539.
hwright marked 11 inline comments as done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185

Files:
  clang-tidy/abseil/AbseilTidyModule.cpp
  clang-tidy/abseil/CMakeLists.txt
  clang-tidy/abseil/DurationAdditionCheck.cpp
  clang-tidy/abseil/DurationAdditionCheck.h
  clang-tidy/abseil/DurationRewriter.cpp
  clang-tidy/abseil/DurationRewriter.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/abseil-duration-addition.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/Inputs/absl/time/time.h
  test/clang-tidy/abseil-duration-addition.cpp

Index: test/clang-tidy/abseil-duration-addition.cpp
===
--- /dev/null
+++ test/clang-tidy/abseil-duration-addition.cpp
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  absl::Time t;
+  int i;
+
+  i = absl::ToUnixHours(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
+  i = absl::ToUnixMinutes(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
+  i = absl::ToUnixSeconds(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+  i = absl::ToUnixMillis(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
+  i = absl::ToUnixMicros(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
+  i = absl::ToUnixNanos(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
+
+  i = 3 + absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+  i = 3 + absl::ToUnixMinutes(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
+  i = 3 + absl::ToUnixSeconds(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
+  i = 3 + absl::ToUnixMillis(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
+  i = 3 + absl::ToUnixMicros(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
+  i = 3 + absl::ToUnixNanos(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
+
+  // Undoing inverse conversions
+  i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
+
+  // Parens
+  i = 3 + (absl::ToUnixHours(t));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+
+  // Float folding
+  i = absl::ToUnixSeconds(t) + 5.0;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+
+  // We can rewrite the argument of the duration conversion
+#define THIRTY absl::FromUnixSeconds(30)
+  i = absl::ToUnixSeconds(THIRTY) + 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
+#undef THIRTY
+
+  // Some other contexts
+  if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
+
+  // These should not match
+  i = 5 + 6;
+  i = absl::ToUnixSeconds(t) - 1.0;
+  i = absl::ToUnixSeconds(t) * 1.0;
+  i = absl::ToUnixSeconds(t) / 1.0;
+  i += 

[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Hyrum Wright via Phabricator via cfe-commits
hwright updated this revision to Diff 183531.
hwright added a comment.

Sort release notes


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185

Files:
  clang-tidy/abseil/AbseilTidyModule.cpp
  clang-tidy/abseil/CMakeLists.txt
  clang-tidy/abseil/DurationAdditionCheck.cpp
  clang-tidy/abseil/DurationAdditionCheck.h
  clang-tidy/abseil/DurationRewriter.cpp
  clang-tidy/abseil/DurationRewriter.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/abseil-duration-addition.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/Inputs/absl/time/time.h
  test/clang-tidy/abseil-duration-addition.cpp

Index: test/clang-tidy/abseil-duration-addition.cpp
===
--- /dev/null
+++ test/clang-tidy/abseil-duration-addition.cpp
@@ -0,0 +1,78 @@
+// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  absl::Time t;
+  int i;
+
+  i = absl::ToUnixHours(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
+  i = absl::ToUnixMinutes(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
+  i = absl::ToUnixSeconds(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+  i = absl::ToUnixMillis(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
+  i = absl::ToUnixMicros(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
+  i = absl::ToUnixNanos(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
+
+  i = 3 + absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+  i = 3 + absl::ToUnixMinutes(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
+  i = 3 + absl::ToUnixSeconds(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
+  i = 3 + absl::ToUnixMillis(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
+  i = 3 + absl::ToUnixMicros(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
+  i = 3 + absl::ToUnixNanos(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
+
+  // Undoing inverse conversions
+  i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
+
+  // Float folding
+  i = absl::ToUnixSeconds(t) + 5.0;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+
+  // We can rewrite the argument of the duration conversion
+#define THIRTY absl::FromUnixSeconds(30)
+  i = absl::ToUnixSeconds(THIRTY) + 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
+#undef THIRTY
+
+  // Some other contexts
+  if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
+
+  // These should not match
+  i = 5 + 6;
+  i = absl::ToUnixSeconds(t) - 1.0;
+  i = absl::ToUnixSeconds(t) * 1.0;
+  i = absl::ToUnixSeconds(t) / 1.0;
+
+#define PLUS_FIVE(z) absl::ToUnixSeconds(z) + 5
+  i = PLUS_FIVE(t);
+#undef PLUS_FIVE
+}
Index: test/clang-tidy/Inputs/absl/time/time.h
===
--- 

[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-25 Thread Jonas Toth via Phabricator via cfe-commits
JonasToth added inline comments.



Comment at: clang-tidy/abseil/DurationAdditionCheck.cpp:22
+void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  binaryOperator(hasOperatorName("+"),

This whole file is structurally similar to the `DurationSubtractionCheck.cpp` 
equivalent (which is expected :)), maybe some parts could be refactored out?
Will there be a check for duration scaling or the like?



Comment at: clang-tidy/abseil/DurationAdditionCheck.cpp:50
+diag(Binop->getBeginLoc(), "perform addition in the duration domain")
+<< FixItHint::CreateReplacement(
+   Binop->getSourceRange(),

The only difference between the two `diag` seems to be the `FixItHint`. I would 
rather refactor the diag out of the `if`.



Comment at: clang-tidy/abseil/DurationAdditionCheck.cpp:60
+  } else {
+assert(Call == Binop->getRHS()->IgnoreImpCast() && "Call should be found 
on the RHS");
+diag(Binop->getBeginLoc(), "perform addition in the duration domain")

What happens with paren-casts, are they ignored as well? (See one comment in 
the test-cases)



Comment at: test/clang-tidy/abseil-duration-addition.cpp:28
+
+  i = 3 + absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration 
domain [abseil-duration-addition]

Call is on the right side, what happens for `3 + (abs::ToUnixHours(t));`



Comment at: test/clang-tidy/abseil-duration-addition.cpp:48
+  // Undoing inverse conversions
+  i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration 
domain [abseil-duration-addition]

Is something like this
```
i += absl::ToInt64MicroSeconds(absl::Seconds(1));
```
possible (syntactically and semantically)?
The compound operators are currently not covered by this (and the 
subtraction-check), but in this case it looks like a possible use-case.


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-24 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: docs/ReleaseNotes.rst:76
 
+- New :doc:`abseil-duration-addition
+  ` check.

Please use alphabetical order for new checks.


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57185/new/

https://reviews.llvm.org/D57185



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57185: [clang-tidy] Add the abseil-duration-addition check

2019-01-24 Thread Hyrum Wright via Phabricator via cfe-commits
hwright created this revision.
hwright added reviewers: hokein, aaron.ballman, JonasToth.
hwright added a project: clang-tools-extra.
Herald added subscribers: cfe-commits, xazax.hun, mgorny.

This is an analog to the existing `abseil-duration-subtraction` check.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D57185

Files:
  clang-tidy/abseil/AbseilTidyModule.cpp
  clang-tidy/abseil/CMakeLists.txt
  clang-tidy/abseil/DurationAdditionCheck.cpp
  clang-tidy/abseil/DurationAdditionCheck.h
  clang-tidy/abseil/DurationRewriter.cpp
  clang-tidy/abseil/DurationRewriter.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/abseil-duration-addition.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/Inputs/absl/time/time.h
  test/clang-tidy/abseil-duration-addition.cpp

Index: test/clang-tidy/abseil-duration-addition.cpp
===
--- /dev/null
+++ test/clang-tidy/abseil-duration-addition.cpp
@@ -0,0 +1,78 @@
+// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs
+
+#include "absl/time/time.h"
+
+void f() {
+  absl::Time t;
+  int i;
+
+  i = absl::ToUnixHours(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5))
+  i = absl::ToUnixMinutes(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5))
+  i = absl::ToUnixSeconds(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+  i = absl::ToUnixMillis(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5))
+  i = absl::ToUnixMicros(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5))
+  i = absl::ToUnixNanos(t) + 5;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5))
+
+  i = 3 + absl::ToUnixHours(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t)
+  i = 3 + absl::ToUnixMinutes(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t)
+  i = 3 + absl::ToUnixSeconds(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t)
+  i = 3 + absl::ToUnixMillis(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t)
+  i = 3 + absl::ToUnixMicros(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t)
+  i = 3 + absl::ToUnixNanos(t);
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t)
+
+  // Undoing inverse conversions
+  i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1));
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1))
+
+  // Float folding
+  i = absl::ToUnixSeconds(t) + 5.0;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5))
+
+  // We can rewrite the argument of the duration conversion
+#define THIRTY absl::FromUnixSeconds(30)
+  i = absl::ToUnixSeconds(THIRTY) + 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1))
+#undef THIRTY
+
+  // Some other contexts
+  if (absl::ToUnixSeconds(t) + 1.0 > 10) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition]
+  // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1))
+
+  // These should not match
+  i = 5 + 6;
+  i = absl::ToUnixSeconds(t) - 1.0;
+  i = absl::ToUnixSeconds(t) * 1.0;
+  i = absl::ToUnixSeconds(t) / 1.0;
+
+#define PLUS_FIVE(z) absl::ToUnixSeconds(z) + 5
+  i = PLUS_FIVE(t);
+#undef