[clang-tidy] Fix PR28406
authorAlexander Kornienko <alexfh@google.com>
Fri, 29 Mar 2019 20:55:29 +0000 (20:55 +0000)
committerAlexander Kornienko <alexfh@google.com>
Fri, 29 Mar 2019 20:55:29 +0000 (20:55 +0000)
Fix the crash resulting from a careless use of getLocWithOffset. At the
beginning of a macro expansion it produces an invalid SourceLocation that causes
an assertion failure later on.

llvm-svn: 357312

clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp
clang-tools-extra/test/clang-tidy/modernize-redundant-void-arg.cpp

index 96eb7a2..46de805 100644 (file)
@@ -101,10 +101,15 @@ void RedundantVoidArgCheck::check(const MatchFinder::MatchResult &Result) {
 void RedundantVoidArgCheck::processFunctionDecl(
     const MatchFinder::MatchResult &Result, const FunctionDecl *Function) {
   if (Function->isThisDeclarationADefinition()) {
-    const Stmt *Body = Function->getBody();
     SourceLocation Start = Function->getBeginLoc();
-    SourceLocation End =
-        Body ? Body->getBeginLoc().getLocWithOffset(-1) : Function->getEndLoc();
+    SourceLocation End = Function->getEndLoc();
+    if (const Stmt *Body = Function->getBody()) {
+      End = Body->getBeginLoc();
+      if (End.isMacroID() &&
+          Result.SourceManager->isAtStartOfImmediateMacroExpansion(End))
+        End = Result.SourceManager->getExpansionLoc(End);
+      End = End.getLocWithOffset(-1);
+    }
     removeVoidArgumentTokens(Result, SourceRange(Start, End),
                              "function definition");
   } else {
@@ -172,10 +177,8 @@ void RedundantVoidArgCheck::removeVoidArgumentTokens(
 
 void RedundantVoidArgCheck::removeVoidToken(Token VoidToken,
                                             StringRef Diagnostic) {
-  SourceLocation VoidLoc(VoidToken.getLocation());
-  auto VoidRange =
-      CharSourceRange::getTokenRange(VoidLoc, VoidLoc.getLocWithOffset(3));
-  diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidRange);
+  SourceLocation VoidLoc = VoidToken.getLocation();
+  diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidLoc);
 }
 
 void RedundantVoidArgCheck::processTypedefNameDecl(
index 44a726b..0fad5d5 100644 (file)
@@ -489,6 +489,13 @@ void lambda_expression_with_macro_test(){
   // CHECK-FIXES: []() BODY;
 }
 
+namespace qqq {
+void foo() BODY
+void bar(void) BODY;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition
+// CHECK-FIXES: void bar() BODY;
+}
+
 struct S_1 {
   void g_1(void) const {
     // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]