r308067 - [clang] Fix handling of "%zd" format specifier

Alexander Shaposhnikov via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 14 15:57:00 PDT 2017


Author: alexshap
Date: Fri Jul 14 15:57:00 2017
New Revision: 308067

URL: http://llvm.org/viewvc/llvm-project?rev=308067&view=rev
Log:
[clang] Fix handling of "%zd" format specifier

This diff addresses FIXME in lib/Analysis/PrintfFormatString.cpp
and makes PrintfSpecifier::getArgType return the correct type. 
In particular, this change enables Clang to emit a warning on 
incorrect using of "%zd"/"%zn" format specifiers.

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

Test plan: make check-all

Modified:
    cfe/trunk/lib/Analysis/PrintfFormatString.cpp
    cfe/trunk/test/FixIt/format.m

Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=308067&r1=308066&r2=308067&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original)
+++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Fri Jul 14 15:57:00 2017
@@ -466,8 +466,7 @@ ArgType PrintfSpecifier::getArgType(ASTC
       case LengthModifier::AsIntMax:
         return ArgType(Ctx.getIntMaxType(), "intmax_t");
       case LengthModifier::AsSizeT:
-        // FIXME: How to get the corresponding signed version of size_t?
-        return ArgType();
+        return ArgType(Ctx.getSignedSizeType(), "ssize_t");
       case LengthModifier::AsInt3264:
         return Ctx.getTargetInfo().getTriple().isArch64Bit()
                    ? ArgType(Ctx.LongLongTy, "__int64")
@@ -537,7 +536,7 @@ ArgType PrintfSpecifier::getArgType(ASTC
       case LengthModifier::AsIntMax:
         return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
       case LengthModifier::AsSizeT:
-        return ArgType(); // FIXME: ssize_t
+        return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
       case LengthModifier::AsPtrDiff:
         return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
       case LengthModifier::AsLongDouble:

Modified: cfe/trunk/test/FixIt/format.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/format.m?rev=308067&r1=308066&r2=308067&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/format.m (original)
+++ cfe/trunk/test/FixIt/format.m Fri Jul 14 15:57:00 2017
@@ -229,6 +229,19 @@ void testSignedness(long i, unsigned lon
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:14}:"%+ld"
 }
 
+void testSizeTypes() {
+  printf("%zu", 0.f); // expected-warning{{format specifies type 'size_t' (aka 'unsigned long') but the argument has type 'float'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+
+  printf("%zd", 0.f); // expected-warning{{format specifies type 'ssize_t' (aka 'long') but the argument has type 'float'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+  
+  int x;
+  printf("%zn", &x); // expected-warning{{format specifies type 'ssize_t *' (aka 'long *') but the argument has type 'int *'}}
+  // PrintfSpecifier::fixType doesn't handle %n, so a fix-it is not emitted, 
+  // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
+}
+
 void testEnum() {
   typedef enum {
     ImplicitA = 1,




More information about the cfe-commits mailing list