Oh, Aaron's "more tests" comment still stands! If not the fixit tests, at least acceptance tests for %Id and %I32d and such.
Jordan On Aug 21, 2013, at 14:54 , David Majnemer <[email protected]> wrote: > Author: majnemer > Date: Wed Aug 21 16:54:46 2013 > New Revision: 188937 > > URL: http://llvm.org/viewvc/llvm-project?rev=188937&view=rev > Log: > Analysis: Add support for MS specific printf format specifiers > > Summary: Adds support for %I, %I32 and %I64. > > Reviewers: hans, jordan_rose, rnk, majnemer > > Reviewed By: majnemer > > CC: cfe-commits, cdavis5x > > Differential Revision: http://llvm-reviews.chandlerc.com/D1456 > > Added: > cfe/trunk/test/Sema/format-strings-ms.c > Modified: > cfe/trunk/include/clang/Analysis/Analyses/FormatString.h > cfe/trunk/lib/Analysis/FormatString.cpp > cfe/trunk/lib/Analysis/PrintfFormatString.cpp > cfe/trunk/lib/Analysis/ScanfFormatString.cpp > > Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=188937&r1=188936&r2=188937&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original) > +++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Wed Aug 21 > 16:54:46 2013 > @@ -73,6 +73,9 @@ public: > AsIntMax, // 'j' > AsSizeT, // 'z' > AsPtrDiff, // 't' > + AsInt32, // 'I32' (MSVCRT, like __int32) > + AsInt3264, // 'I' (MSVCRT, like __int3264 from MIDL) > + AsInt64, // 'I64' (MSVCRT, like __int64) > AsLongDouble, // 'L' > AsAllocate, // for '%as', GNU extension to C90 scanf > AsMAllocate, // for '%ms', GNU extension to scanf > @@ -95,6 +98,9 @@ public: > case AsLongLong: > case AsChar: > return 2; > + case AsInt32: > + case AsInt64: > + return 3; > case None: > return 0; > } > > Modified: cfe/trunk/lib/Analysis/FormatString.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/FormatString.cpp?rev=188937&r1=188936&r2=188937&view=diff > ============================================================================== > --- cfe/trunk/lib/Analysis/FormatString.cpp (original) > +++ cfe/trunk/lib/Analysis/FormatString.cpp Wed Aug 21 16:54:46 2013 > @@ -223,6 +223,27 @@ clang::analyze_format_string::ParseLengt > break; > } > return false; > + // printf: AsInt64, AsInt32, AsInt3264 > + // scanf: AsInt64 > + case 'I': > + if (I + 1 != E && I + 2 != E) { > + if (I[1] == '6' && I[2] == '4') { > + I += 3; > + lmKind = LengthModifier::AsInt64; > + break; > + } > + if (IsScanf) > + return false; > + > + if (I[1] == '3' && I[2] == '2') { > + I += 3; > + lmKind = LengthModifier::AsInt32; > + break; > + } > + } > + ++I; > + lmKind = LengthModifier::AsInt3264; > + break; > } > LengthModifier lm(lmPosition, lmKind); > FS.setLengthModifier(lm); > @@ -471,6 +492,12 @@ analyze_format_string::LengthModifier::t > return "z"; > case AsPtrDiff: > return "t"; > + case AsInt32: > + return "I32"; > + case AsInt3264: > + return "I"; > + case AsInt64: > + return "I64"; > case AsLongDouble: > return "L"; > case AsAllocate: > @@ -514,7 +541,7 @@ const char *ConversionSpecifier::toStrin > case ScanListArg: return "["; > case InvalidSpecifier: return NULL; > > - // MacOS X unicode extensions. > + // POSIX unicode extensions. > case CArg: return "C"; > case SArg: return "S"; > > @@ -678,6 +705,20 @@ bool FormatSpecifier::hasValidLengthModi > default: > return false; > } > + case LengthModifier::AsInt32: > + case LengthModifier::AsInt3264: > + case LengthModifier::AsInt64: > + switch (CS.getKind()) { > + case ConversionSpecifier::dArg: > + case ConversionSpecifier::iArg: > + case ConversionSpecifier::oArg: > + case ConversionSpecifier::uArg: > + case ConversionSpecifier::xArg: > + case ConversionSpecifier::XArg: > + return Target.getTriple().isOSMSVCRT(); > + default: > + return false; > + } > } > llvm_unreachable("Invalid LengthModifier Kind!"); > } > @@ -697,6 +738,9 @@ bool FormatSpecifier::hasStandardLengthM > case LengthModifier::AsAllocate: > case LengthModifier::AsMAllocate: > case LengthModifier::AsQuad: > + case LengthModifier::AsInt32: > + case LengthModifier::AsInt3264: > + case LengthModifier::AsInt64: > return false; > } > llvm_unreachable("Invalid LengthModifier Kind!"); > > Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/PrintfFormatString.cpp?rev=188937&r1=188936&r2=188937&view=diff > ============================================================================== > --- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original) > +++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Wed Aug 21 16:54:46 2013 > @@ -187,8 +187,8 @@ static PrintfSpecifierResult ParsePrintf > case 'i': k = ConversionSpecifier::iArg; break; > case 'n': k = ConversionSpecifier::nArg; break; > case 'o': k = ConversionSpecifier::oArg; break; > - case 'p': k = ConversionSpecifier::pArg; break; > - case 's': k = ConversionSpecifier::sArg; break; > + case 'p': k = ConversionSpecifier::pArg; break; > + case 's': k = ConversionSpecifier::sArg; break; > case 'u': k = ConversionSpecifier::uArg; break; > case 'x': k = ConversionSpecifier::xArg; break; > // POSIX specific. > @@ -278,18 +278,26 @@ ArgType PrintfSpecifier::getArgType(ASTC > case LengthModifier::AsLongDouble: > // GNU extension. > return Ctx.LongLongTy; > - case LengthModifier::None: return Ctx.IntTy; > + case LengthModifier::None: > + return Ctx.IntTy; > + case LengthModifier::AsInt32: > + return ArgType(Ctx.IntTy, "__int32"); > case LengthModifier::AsChar: return ArgType::AnyCharTy; > case LengthModifier::AsShort: return Ctx.ShortTy; > case LengthModifier::AsLong: return Ctx.LongTy; > case LengthModifier::AsLongLong: > case LengthModifier::AsQuad: > return Ctx.LongLongTy; > + case LengthModifier::AsInt64: > + return ArgType(Ctx.LongLongTy, "__int64"); > 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(); > + case LengthModifier::AsInt3264: > + return Ctx.getTargetInfo().getTriple().isArch64Bit() ? Ctx.LongLongTy > + : Ctx.IntTy; > case LengthModifier::AsPtrDiff: > return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"); > case LengthModifier::AsAllocate: > @@ -302,17 +310,26 @@ ArgType PrintfSpecifier::getArgType(ASTC > case LengthModifier::AsLongDouble: > // GNU extension. > return Ctx.UnsignedLongLongTy; > - case LengthModifier::None: return Ctx.UnsignedIntTy; > + case LengthModifier::None: > + return Ctx.UnsignedIntTy; > + case LengthModifier::AsInt32: > + return ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); > case LengthModifier::AsChar: return Ctx.UnsignedCharTy; > case LengthModifier::AsShort: return Ctx.UnsignedShortTy; > case LengthModifier::AsLong: return Ctx.UnsignedLongTy; > case LengthModifier::AsLongLong: > case LengthModifier::AsQuad: > return Ctx.UnsignedLongLongTy; > + case LengthModifier::AsInt64: > + return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64"); > case LengthModifier::AsIntMax: > return ArgType(Ctx.getUIntMaxType(), "uintmax_t"); > case LengthModifier::AsSizeT: > return ArgType(Ctx.getSizeType(), "size_t"); > + case LengthModifier::AsInt3264: > + return Ctx.getTargetInfo().getTriple().isArch64Bit() > + ? Ctx.UnsignedLongLongTy > + : Ctx.UnsignedIntTy; > case LengthModifier::AsPtrDiff: > // FIXME: How to get the corresponding unsigned > // version of ptrdiff_t? > @@ -351,6 +368,9 @@ ArgType PrintfSpecifier::getArgType(ASTC > return ArgType(); // FIXME: Is this a known extension? > case LengthModifier::AsAllocate: > case LengthModifier::AsMAllocate: > + case LengthModifier::AsInt32: > + case LengthModifier::AsInt3264: > + case LengthModifier::AsInt64: > return ArgType::Invalid(); > } > } > > Modified: cfe/trunk/lib/Analysis/ScanfFormatString.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ScanfFormatString.cpp?rev=188937&r1=188936&r2=188937&view=diff > ============================================================================== > --- cfe/trunk/lib/Analysis/ScanfFormatString.cpp (original) > +++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp Wed Aug 21 16:54:46 2013 > @@ -232,6 +232,8 @@ ArgType ScanfSpecifier::getArgType(ASTCo > case LengthModifier::AsLongLong: > case LengthModifier::AsQuad: > return ArgType::PtrTo(Ctx.LongLongTy); > + case LengthModifier::AsInt64: > + return ArgType::PtrTo(ArgType(Ctx.LongLongTy, "__int64")); > case LengthModifier::AsIntMax: > return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); > case LengthModifier::AsSizeT: > @@ -243,8 +245,9 @@ ArgType ScanfSpecifier::getArgType(ASTCo > // GNU extension. > return ArgType::PtrTo(Ctx.LongLongTy); > case LengthModifier::AsAllocate: > - return ArgType::Invalid(); > case LengthModifier::AsMAllocate: > + case LengthModifier::AsInt32: > + case LengthModifier::AsInt3264: > return ArgType::Invalid(); > } > > @@ -267,6 +270,8 @@ ArgType ScanfSpecifier::getArgType(ASTCo > case LengthModifier::AsLongLong: > case LengthModifier::AsQuad: > return ArgType::PtrTo(Ctx.UnsignedLongLongTy); > + case LengthModifier::AsInt64: > + return ArgType::PtrTo(ArgType(Ctx.UnsignedLongLongTy, "unsigned > __int64")); > case LengthModifier::AsIntMax: > return ArgType::PtrTo(ArgType(Ctx.getUIntMaxType(), "uintmax_t")); > case LengthModifier::AsSizeT: > @@ -278,8 +283,9 @@ ArgType ScanfSpecifier::getArgType(ASTCo > // GNU extension. > return ArgType::PtrTo(Ctx.UnsignedLongLongTy); > case LengthModifier::AsAllocate: > - return ArgType::Invalid(); > case LengthModifier::AsMAllocate: > + case LengthModifier::AsInt32: > + case LengthModifier::AsInt3264: > return ArgType::Invalid(); > } > > @@ -349,6 +355,8 @@ ArgType ScanfSpecifier::getArgType(ASTCo > case LengthModifier::AsLongLong: > case LengthModifier::AsQuad: > return ArgType::PtrTo(Ctx.LongLongTy); > + case LengthModifier::AsInt64: > + return ArgType::PtrTo(ArgType(Ctx.LongLongTy, "__int64")); > case LengthModifier::AsIntMax: > return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); > case LengthModifier::AsSizeT: > @@ -359,6 +367,8 @@ ArgType ScanfSpecifier::getArgType(ASTCo > return ArgType(); // FIXME: Is this a known extension? > case LengthModifier::AsAllocate: > case LengthModifier::AsMAllocate: > + case LengthModifier::AsInt32: > + case LengthModifier::AsInt3264: > return ArgType::Invalid(); > } > > > Added: cfe/trunk/test/Sema/format-strings-ms.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-ms.c?rev=188937&view=auto > ============================================================================== > --- cfe/trunk/test/Sema/format-strings-ms.c (added) > +++ cfe/trunk/test/Sema/format-strings-ms.c Wed Aug 21 16:54:46 2013 > @@ -0,0 +1,9 @@ > +// RUN: %clang_cc1 -fsyntax-only -verify -fms-compatibility > -triple=i386-pc-win32 -pedantic %s > + > +int printf(const char *format, ...) __attribute__((format(printf, 1, 2))); > + > +void test() { > + short val = 30; > + printf("val = %I64d\n", val); // expected-warning{{'I64' length modifier > is not supported by ISO C}} \ > + // expected-warning{{format specifies type > '__int64' (aka 'long long') but the argument has type 'short'}} > +} > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
