r188937 - Analysis: Add support for MS specific printf format specifiers

David Majnemer david.majnemer at gmail.com
Thu Aug 22 00:55:45 PDT 2013


Add more in r188992.


On Wed, Aug 21, 2013 at 3:27 PM, Jordan Rose <jordan_rose at apple.com> wrote:

> 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 <david.majnemer at gmail.com>
> 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
> > cfe-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130822/8b372847/attachment.html>


More information about the cfe-commits mailing list