aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorShoaib Meenai <smeenai@fb.com>2023-09-20 17:32:35 -0700
committerGitHub <noreply@github.com>2023-09-20 17:32:35 -0700
commit61c5ad8857a71510e4393680a1e42740da4ba6fa (patch)
tree31cd42a40a1f41cda47b79a65ae20ba81488388e /clang/lib/Sema/SemaChecking.cpp
parentea064ba6a2d50b1ff440be7d3a9237ddb7afe355 (diff)
downloadllvm-61c5ad8857a71510e4393680a1e42740da4ba6fa.zip
llvm-61c5ad8857a71510e4393680a1e42740da4ba6fa.tar.gz
llvm-61c5ad8857a71510e4393680a1e42740da4ba6fa.tar.bz2
[Sema] Fix fixit cast printing inside macros (#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. Before this, format fix-its would omit the closing parenthesis (thus producing invalid code) for macros, e.g.: ``` $ cat format.cpp extern "C" int printf(const char *, ...); enum class Foo { Bar }; #define LOG(...) printf(__VA_ARGS__) void f(Foo foo) { LOG("%d\n", foo); } $ clang -fsyntax-only format.cpp format.cpp:4:29: warning: format specifies type 'int' but the argument has type 'Foo' [-Wformat] 4 | void f(Foo f) { LOG("%d\n", f); } | ~~ ^ | static_cast<int>( format.cpp:3:25: note: expanded from macro 'LOG' 3 | #define LOG(...) printf(__VA_ARGS__) | ^~~~~~~~~~~ 1 warning generated. ``` We now emit a valid fix-it: ``` $ clang -fsyntax-only format.cpp format.cpp:4:31: warning: format specifies type 'int' but the argument has type 'Foo' [-Wformat] 4 | void f(Foo foo) { LOG("%d\n", foo); } | ~~ ^~~ | static_cast<int>( ) format.cpp:3:25: note: expanded from macro 'LOG' 3 | #define LOG(...) printf(__VA_ARGS__) | ^~~~~~~~~~~ 1 warning generated. ``` Fixes https://github.com/llvm/llvm-project/issues/63462
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp6
1 files changed, 5 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index fad7022..b867d55 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11470,7 +11470,11 @@ 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 EndLoc = S.SourceMgr.getSpellingLoc(E->getEndLoc());
+ SourceLocation After = EndLoc.getLocWithOffset(
+ Lexer::MeasureTokenLength(EndLoc, S.SourceMgr, S.LangOpts));
Hints.push_back(FixItHint::CreateInsertion(After, ")"));
}