[PATCH] Analysis: Add support for MS specific printf format specifiers
Aaron Ballman
aaron at aaronballman.com
Wed Aug 21 05:42:14 PDT 2013
> Index: include/clang/Analysis/Analyses/FormatString.h
> ===================================================================
> --- include/clang/Analysis/Analyses/FormatString.h
> +++ include/clang/Analysis/Analyses/FormatString.h
> @@ -73,6 +73,9 @@
> AsIntMax, // 'j'
> AsSizeT, // 'z'
> AsPtrDiff, // 't'
> + AsInt32, // 'I32' (MSVCRT, like __int32)
> + AsInt3264, // 'I' (MSVCRT, like size_t/ptrdiff_t)
> + AsInt64, // 'I64' (MSVCRT, like __int64)
> AsLongDouble, // 'L'
> AsAllocate, // for '%as', GNU extension to C90 scanf
> AsMAllocate, // for '%ms', GNU extension to scanf
> Index: lib/Analysis/FormatString.cpp
> ===================================================================
> --- lib/Analysis/FormatString.cpp
> +++ lib/Analysis/FormatString.cpp
> @@ -223,6 +223,27 @@
> 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::AsInt64;
Shouldn't this be AsInt32?
> + break;
> + }
> + }
> + ++I;
> + lmKind = LengthModifier::AsInt3264;
> + break;
> }
> LengthModifier lm(lmPosition, lmKind);
> FS.setLengthModifier(lm);
> @@ -471,6 +492,12 @@
> 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 @@
> 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 @@
> 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 @@
> 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!");
> Index: lib/Analysis/PrintfFormatString.cpp
> ===================================================================
> --- lib/Analysis/PrintfFormatString.cpp
> +++ lib/Analysis/PrintfFormatString.cpp
> @@ -187,8 +187,8 @@
> 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,24 @@
> case LengthModifier::AsLongDouble:
> // GNU extension.
> return Ctx.LongLongTy;
> - case LengthModifier::None: return Ctx.IntTy;
> + case LengthModifier::None:
> + case LengthModifier::AsInt32:
> + return Ctx.IntTy;
> case LengthModifier::AsChar: return ArgType::AnyCharTy;
> case LengthModifier::AsShort: return Ctx.ShortTy;
> case LengthModifier::AsLong: return Ctx.LongTy;
> case LengthModifier::AsLongLong:
> case LengthModifier::AsQuad:
> + case LengthModifier::AsInt64:
> return Ctx.LongLongTy;
> 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 +308,24 @@
> case LengthModifier::AsLongDouble:
> // GNU extension.
> return Ctx.UnsignedLongLongTy;
> - case LengthModifier::None: return Ctx.UnsignedIntTy;
> + case LengthModifier::None:
> + case LengthModifier::AsInt32:
> + return Ctx.UnsignedIntTy;
> case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
> case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
> case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
> case LengthModifier::AsLongLong:
> case LengthModifier::AsQuad:
> + case LengthModifier::AsInt64:
> return Ctx.UnsignedLongLongTy;
> 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 +364,9 @@
> 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();
> }
> }
> Index: lib/Analysis/ScanfFormatString.cpp
> ===================================================================
> --- lib/Analysis/ScanfFormatString.cpp
> +++ lib/Analysis/ScanfFormatString.cpp
> @@ -231,6 +231,7 @@
> return ArgType::PtrTo(Ctx.LongTy);
> case LengthModifier::AsLongLong:
> case LengthModifier::AsQuad:
> + case LengthModifier::AsInt64:
> return ArgType::PtrTo(Ctx.LongLongTy);
> case LengthModifier::AsIntMax:
> return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
> @@ -243,8 +244,9 @@
> // 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();
> }
>
> @@ -266,6 +268,7 @@
> return ArgType::PtrTo(Ctx.UnsignedLongTy);
> case LengthModifier::AsLongLong:
> case LengthModifier::AsQuad:
> + case LengthModifier::AsInt64:
> return ArgType::PtrTo(Ctx.UnsignedLongLongTy);
> case LengthModifier::AsIntMax:
> return ArgType::PtrTo(ArgType(Ctx.getUIntMaxType(), "uintmax_t"));
> @@ -278,8 +281,9 @@
> // 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();
> }
>
> @@ -359,6 +363,9 @@
> 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();
> }
>
> Index: test/Sema/format-strings-ms.c
> ===================================================================
> --- /dev/null
> +++ test/Sema/format-strings-ms.c
> @@ -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 'long long' but the argument has type 'short'}}
> +}
>
Should also have tests for I32 and I.
Otherwise, patch LGTM!
~Aaron
On Wed, Aug 21, 2013 at 5:01 AM, David Majnemer
<david.majnemer at gmail.com> wrote:
> Hi hans, jordan_rose, rnk,
>
> Adds support for %I, %I32 and %I64.
>
> http://llvm-reviews.chandlerc.com/D1456
>
> Files:
> include/clang/Analysis/Analyses/FormatString.h
> lib/Analysis/FormatString.cpp
> lib/Analysis/PrintfFormatString.cpp
> lib/Analysis/ScanfFormatString.cpp
> test/Sema/format-strings-ms.c
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list