[clang] 3c0a136 - [clang][Sema] Suggest static_cast in C++ code
Alex Brachet via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 14 09:24:52 PDT 2023
Author: Alex Brachet
Date: 2023-07-14T16:22:06Z
New Revision: 3c0a136ce4b724221a7f75b656b9f7af3de6b64c
URL: https://github.com/llvm/llvm-project/commit/3c0a136ce4b724221a7f75b656b9f7af3de6b64c
DIFF: https://github.com/llvm/llvm-project/commit/3c0a136ce4b724221a7f75b656b9f7af3de6b64c.diff
LOG: [clang][Sema] Suggest static_cast in C++ code
This patch changes the -Wformat diagnostic to suggest static_cast over
a C-style cast for {,Objective}C++ when recommending the argument be
casted rather than changing the format string.
Before:
```
clang/test/FixIt/format.mm:11:16: warning: format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t' [-Wformat]
11 | NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
| ~~ ^~~~~~~~~~
| (unsigned short)
```
After:
```
clang/test/FixIt/format.mm:11:16: warning: format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t' [-Wformat]
11 | NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
| ~~ ^~~~~~~~~~
| static_cast<unsigned short>( )
```
Differential Revision: https://reviews.llvm.org/D153622
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaChecking.cpp
clang/test/FixIt/format.mm
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 53a83b9c94176d..0423c054bd0b58 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -415,6 +415,8 @@ Improvements to Clang's diagnostics
source:1:6: note: candidate function not viable: no known conversion from 'const char[4]' to 'int' for 2nd argument
void func(int aa, int bb);
^ ~~~~~~
+- ``-Wformat`` cast fix-its will now suggest ``static_cast`` instead of C-style casts
+ for C++ code.
Bug Fixes in This Version
-------------------------
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index f9a50f6ef3be6f..66a1a8f3f90ee3 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11184,9 +11184,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
// if necessary).
SmallString<16> CastBuf;
llvm::raw_svector_ostream CastFix(CastBuf);
- CastFix << "(";
+ CastFix << (S.LangOpts.CPlusPlus ? "static_cast<" : "(");
IntendedTy.print(CastFix, S.Context.getPrintingPolicy());
- CastFix << ")";
+ CastFix << (S.LangOpts.CPlusPlus ? ">" : ")");
SmallVector<FixItHint,4> Hints;
if (!AT.matchesType(S.Context, IntendedTy) || ShouldNotPrintDirectly)
@@ -11197,7 +11197,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
Hints.push_back(FixItHint::CreateReplacement(CastRange, CastFix.str()));
- } else if (!requiresParensToAddCast(E)) {
+ } else if (!requiresParensToAddCast(E) && !S.LangOpts.CPlusPlus) {
// If the expression has high enough precedence,
// just write the C-style cast.
Hints.push_back(
diff --git a/clang/test/FixIt/format.mm b/clang/test/FixIt/format.mm
index eed7c981f2c455..f630db41b37844 100644
--- a/clang/test/FixIt/format.mm
+++ b/clang/test/FixIt/format.mm
@@ -9,22 +9,22 @@ void test_percent_C() {
const wchar_t wchar_data = L'a';
NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unsigned short)"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"static_cast<unsigned short>(
NSLog(@"%C", 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unsigned short)"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"static_cast<unsigned short>(
typedef unsigned short unichar;
NSLog(@"%C", wchar_data); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'wchar_t'}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"(unichar)"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:16-[[@LINE-1]]:16}:"static_cast<unichar>(
NSLog(@"%C", 0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'int'}}
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
- // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"static_cast<unichar>(
NSLog(@"%C", 0.0); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'double'}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%f"
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
+ // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"static_cast<unichar>(
}
More information about the cfe-commits
mailing list