[clang] fe0d1b6 - [Clang] Warn about 'z' printf modifier in old MSVC.
Simon Tatham via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 28 01:04:56 PST 2020
Author: Simon Tatham
Date: 2020-01-28T09:04:45Z
New Revision: fe0d1b6a8ac5048b8007e5e7cc2aeb4e3291bda0
URL: https://github.com/llvm/llvm-project/commit/fe0d1b6a8ac5048b8007e5e7cc2aeb4e3291bda0
DIFF: https://github.com/llvm/llvm-project/commit/fe0d1b6a8ac5048b8007e5e7cc2aeb4e3291bda0.diff
LOG: [Clang] Warn about 'z' printf modifier in old MSVC.
Summary:
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 a value earlier than
MSVC2015, it's useful to warn about 'z' modifiers in printf format
strings we check.
Reviewers: aaron.ballman, lebedev.ri, rnk, majnemer, zturner
Reviewed By: aaron.ballman
Subscribers: amccarth, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D73457
Added:
Modified:
clang/lib/AST/FormatString.cpp
clang/test/Sema/format-strings-ms.c
Removed:
################################################################################
diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp
index fcc0b3b11e25..2ca8fee67bf0 100644
--- a/clang/lib/AST/FormatString.cpp
+++ b/clang/lib/AST/FormatString.cpp
@@ -748,6 +748,15 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
case LengthModifier::AsIntMax:
case LengthModifier::AsSizeT:
case LengthModifier::AsPtrDiff:
+ if (LM.getKind() == LengthModifier::AsSizeT &&
+ Target.getTriple().isOSMSVCRT() &&
+ !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 less than
+ // that, reject.
+ return false;
+ }
+
switch (CS.getKind()) {
case ConversionSpecifier::dArg:
case ConversionSpecifier::DArg:
diff --git a/clang/test/Sema/format-strings-ms.c b/clang/test/Sema/format-strings-ms.c
index 56a349051d42..c4d3e5664db0 100644
--- a/clang/test/Sema/format-strings-ms.c
+++ b/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=18 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility -triple=i386-pc-win32 -fms-compatibility-version=19 -DSIZE_T_OK %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 @@ void z_test(void *p) {
scanf("%Z", p); // expected-warning{{invalid conversion specifier 'Z'}}
}
+void size_t_test(size_t s) {
+ printf("%zu", s);
+#ifndef SIZE_T_OK
+ // expected-warning at -2 {{length modifier 'z' results in undefined behavior or no effect with 'u' conversion specifier}}
+#endif
+}
+
#endif
More information about the cfe-commits
mailing list