diff options
author | Shoaib Meenai <smeenai@fb.com> | 2023-09-20 17:32:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-20 17:32:35 -0700 |
commit | 61c5ad8857a71510e4393680a1e42740da4ba6fa (patch) | |
tree | 31cd42a40a1f41cda47b79a65ae20ba81488388e /clang/lib/Sema/SemaChecking.cpp | |
parent | ea064ba6a2d50b1ff440be7d3a9237ddb7afe355 (diff) | |
download | llvm-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.cpp | 6 |
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, ")")); } |