[clang] 4f8e299 - [Sema] Fix diagnostics for one-byte length modifier

Anton Bikineev via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 9 07:57:08 PST 2021


Author: Anton Bikineev
Date: 2021-03-09T16:56:20+01:00
New Revision: 4f8e299785e860cf974d696d7ca83b70a94977fe

URL: https://github.com/llvm/llvm-project/commit/4f8e299785e860cf974d696d7ca83b70a94977fe
DIFF: https://github.com/llvm/llvm-project/commit/4f8e299785e860cf974d696d7ca83b70a94977fe.diff

LOG: [Sema] Fix diagnostics for one-byte length modifier

In case a char-literal of type int (C/ObjectiveC) corresponds to a
format specifier with the %hh length modifier, don't treat the literal
as of type char for issuing diagnostics, as otherwise this results in:

printf("%hhd", 'e');
warning: format specifies type 'char' but the argument has type 'char'.

Differential revision: https://reviews.llvm.org/D97951

Added: 
    

Modified: 
    clang/lib/Sema/SemaChecking.cpp
    clang/test/FixIt/format.m

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index fef6a9306eaf..e390159a8f64 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -8730,8 +8730,11 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
   } else if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) {
     // Special case for 'a', which has type 'int' in C.
     // Note, however, that we do /not/ want to treat multibyte constants like
-    // 'MooV' as characters! This form is deprecated but still exists.
-    if (ExprTy == S.Context.IntTy)
+    // 'MooV' as characters! This form is deprecated but still exists. In
+    // addition, don't treat expressions as of type 'char' if one byte length
+    // modifier is provided.
+    if (ExprTy == S.Context.IntTy &&
+        FS.getLengthModifier().getKind() != LengthModifier::AsChar)
       if (llvm::isUIntN(S.Context.getCharWidth(), CL->getValue()))
         ExprTy = S.Context.CharTy;
   }

diff  --git a/clang/test/FixIt/format.m b/clang/test/FixIt/format.m
index ef27b1bac353..0d173846d0ad 100644
--- a/clang/test/FixIt/format.m
+++ b/clang/test/FixIt/format.m
@@ -169,6 +169,12 @@ void test_char(char c, signed char s, unsigned char u, uint8_t n) {
 
   NSLog(@"%@", 'abcd'); // expected-warning{{format specifies type 'id' but the argument has type 'int'}}
   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%d"
+
+  NSLog(@"%hhd", 'a'); // expected-warning{{format specifies type 'char' but the argument has type 'int'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:15}:"%d"
+
+  NSLog(@"%hhu", 'a'); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'int'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:15}:"%d"
 }
 
 void multichar_constants_false_negative() {


        


More information about the cfe-commits mailing list