[clang] [Sema] Fix fixit cast printing inside macros (PR #66853)

Shoaib Meenai via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 19 19:55:59 PDT 2023


https://github.com/smeenai created https://github.com/llvm/llvm-project/pull/66853

`Lexer::getLocForEndOfToken` is documented as returning an invalid
source location when the end of the token is inside a macro expansion.
We don't want that for this particular application, so just calculate
the end location directly instead.

Fixes https://github.com/llvm/llvm-project/issues/63462


>From 66e12c0c192f6b490be5df694b2d7faedd1d1b74 Mon Sep 17 00:00:00 2001
From: Shoaib Meenai <smeenai at fb.com>
Date: Tue, 19 Sep 2023 19:46:56 -0700
Subject: [PATCH] [Sema] Fix fixit cast printing inside macros

`Lexer::getLocForEndOfToken` is documented as returning an invalid
source location when the end of the token is inside a macro expansion.
We don't want that for this particular application, so just calculate
the end location directly instead.

Fixes https://github.com/llvm/llvm-project/issues/63462
---
 clang/lib/Sema/SemaChecking.cpp | 5 ++++-
 clang/test/FixIt/format.cpp     | 5 +++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index fad70223362eddd..4fbdb315ddc87b4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11470,7 +11470,10 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
         Hints.push_back(
             FixItHint::CreateInsertion(E->getBeginLoc(), CastFix.str()));
 
-        SourceLocation After = S.getLocForEndOfToken(E->getEndLoc());
+        // We don't use getLocForEndOfToken because it returns invalid source
+        // locations for macro expansions (by design).
+        SourceLocation After = E->getEndLoc().getLocWithOffset(
+            Lexer::MeasureTokenLength(E->getEndLoc(), S.SourceMgr, S.LangOpts));
         Hints.push_back(FixItHint::CreateInsertion(After, ")"));
       }
 
diff --git a/clang/test/FixIt/format.cpp b/clang/test/FixIt/format.cpp
index 9cc4c2600eb6670..46a0a0a11cc850a 100644
--- a/clang/test/FixIt/format.cpp
+++ b/clang/test/FixIt/format.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wformat %s 2>&1 | FileCheck %s
 
 extern "C" int printf(const char *, ...);
+#define LOG(...) printf(__VA_ARGS__)
 
 namespace N {
   enum class E { One };
@@ -16,4 +17,8 @@ void a() {
 
   printf("%hu", N::E::One);
   // CHECK: "static_cast<unsigned short>("
+
+  LOG("%d", N::E::One); // expected-warning{{format specifies type 'int' but the argument has type 'N::E'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:"static_cast<int>("
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:22-[[@LINE-2]]:22}:")"
 }



More information about the cfe-commits mailing list