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@-2 {{length modifier 'z' results in undefined behavior or no effect with 'u' conversion specifier}} +#endif +} + #endif _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits