[PATCH] D73457: [Clang] Warn about 'z' printf modifier in old MSVC.

Simon Tatham via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 27 03:11:44 PST 2020


simon_tatham created this revision.
simon_tatham added reviewers: aaron.ballman, lebedev.ri.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The 'z' length modifier, signalling that an integer format specifier
takes a `size_t` sized integer, is only supported by the C library of
MSVC 2015 and later. Earlier versions don't recognize the 'z' at all,
and respond to `printf("%zu", x)` by just printing "zu".

So, if the MS compatibility version is set to something specific which
is earlier than 2015, it's useful to warn about 'z' modifiers in
printf format strings we check.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73457

Files:
  clang/include/clang/Basic/LangOptions.h
  clang/lib/AST/FormatString.cpp
  clang/test/Sema/format-strings-ms.c


Index: clang/test/Sema/format-strings-ms.c
===================================================================
--- clang/test/Sema/format-strings-ms.c
+++ clang/test/Sema/format-strings-ms.c
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -triple=i386-pc-win32 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -triple=i386-pc-win32 -fms-compatibility-version=19 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -triple=i386-pc-win32 -fms-compatibility-version=18 -DNO_z_MODIFIER %s
 // RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -triple=i386-pc-win32 -Wformat-non-iso -DNON_ISO_WARNING %s
 
 int printf(const char *format, ...) __attribute__((format(printf, 1, 2)));
@@ -85,4 +87,11 @@
   scanf("%Z", p); // expected-warning{{invalid conversion specifier 'Z'}}
 }
 
+void size_t_test(size_t s) {
+  printf("%zu", s);
+#ifdef NO_z_MODIFIER
+  // expected-warning at -2 {{length modifier 'z' results in undefined behavior or no effect with 'u' conversion specifier}}
+#endif
+}
+
 #endif
Index: clang/lib/AST/FormatString.cpp
===================================================================
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -748,6 +748,16 @@
     case LengthModifier::AsIntMax:
     case LengthModifier::AsSizeT:
     case LengthModifier::AsPtrDiff:
+      if (LM.getKind() == LengthModifier::AsSizeT &&
+          Target.getTriple().isOSMSVCRT() &&
+          LO.isMSCompatibilityVersionSpecified() &&
+          !LO.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
+        // The standard libraries before MSVC2015 didn't support the 'z' length
+        // modifier for size_t. So if the MS compatibility version is specified
+        // and less than that, reject.
+        return false;
+      }
+
       switch (CS.getKind()) {
         case ConversionSpecifier::dArg:
         case ConversionSpecifier::DArg:
Index: clang/include/clang/Basic/LangOptions.h
===================================================================
--- clang/include/clang/Basic/LangOptions.h
+++ clang/include/clang/Basic/LangOptions.h
@@ -328,6 +328,10 @@
            !ObjCSubscriptingLegacyRuntime;
   }
 
+  bool isMSCompatibilityVersionSpecified() const {
+    return MSCompatibilityVersion != 0;
+  }
+
   bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
     return MSCompatibilityVersion >= MajorVersion * 100000U;
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D73457.240516.patch
Type: text/x-patch
Size: 2435 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200127/cc83a35c/attachment.bin>


More information about the cfe-commits mailing list