[clang-tidy] Fix crash on end location inside macro
authorNathan Huckleberry <nhuck@google.com>
Wed, 17 Jul 2019 17:22:43 +0000 (17:22 +0000)
committerNathan Huckleberry <nhuck@google.com>
Wed, 17 Jul 2019 17:22:43 +0000 (17:22 +0000)
Summary:
Lexer::getLocForEndOfToken is defined to return an
invalid location if the given location is inside a macro.
Other checks conditionally warn based off location
validity. Updating this check to do the same.

Reviewers: JonasToth, aaron.ballman, nickdesaulniers

Reviewed By: nickdesaulniers

Subscribers: lebedev.ri, nickdesaulniers, xazax.hun, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D64607

llvm-svn: 366353

clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp
clang-tools-extra/test/clang-tidy/bugprone-branch-clone-macro-crash.c [new file with mode: 0644]

index a898311..eb54aaa 100644 (file)
@@ -132,9 +132,12 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) {
           // We report the first occurence only when we find the second one.
           diag(Branches[i]->getBeginLoc(),
                "repeated branch in conditional chain");
-          diag(Lexer::getLocForEndOfToken(Branches[i]->getEndLoc(), 0,
-                                          *Result.SourceManager, getLangOpts()),
-               "end of the original", DiagnosticIDs::Note);
+          SourceLocation End =
+              Lexer::getLocForEndOfToken(Branches[i]->getEndLoc(), 0,
+                                         *Result.SourceManager, getLangOpts());
+          if (End.isValid()) {
+            diag(End, "end of the original", DiagnosticIDs::Note);
+          }
         }
 
         diag(Branches[j]->getBeginLoc(), "clone %0 starts here",
@@ -208,10 +211,12 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) {
 
         if (EndLoc.isMacroID())
           EndLoc = Context.getSourceManager().getExpansionLoc(EndLoc);
+        EndLoc = Lexer::getLocForEndOfToken(EndLoc, 0, *Result.SourceManager,
+                                            getLangOpts());
 
-        diag(Lexer::getLocForEndOfToken(EndLoc, 0, *Result.SourceManager,
-                                        getLangOpts()),
-             "last of these clones ends here", DiagnosticIDs::Note);
+        if (EndLoc.isValid()) {
+          diag(EndLoc, "last of these clones ends here", DiagnosticIDs::Note);
+        }
       }
       BeginCurrent = EndCurrent;
     }
diff --git a/clang-tools-extra/test/clang-tidy/bugprone-branch-clone-macro-crash.c b/clang-tools-extra/test/clang-tidy/bugprone-branch-clone-macro-crash.c
new file mode 100644 (file)
index 0000000..ce0c013
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: %check_clang_tidy %s bugprone-branch-clone %t
+int x = 0;
+int y = 1;
+#define a(b, c) \
+  typeof(b) d;  \
+  if (b)        \
+    d = b;      \
+  else if (c)   \
+    d = b;
+
+f() {
+  // CHECK-MESSAGES: warning: repeated branch in conditional chain [bugprone-branch-clone]
+  a(x, y)
+}