Home | History | Annotate | Download | only in Analysis
      1 //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Handling of format string in printf and friends.  The structure of format
     11 // strings for fprintf() are described in C99 7.19.6.1.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "clang/Analysis/Analyses/FormatString.h"
     16 #include "FormatStringParsing.h"
     17 #include "clang/Basic/TargetInfo.h"
     18 
     19 using clang::analyze_format_string::ArgType;
     20 using clang::analyze_format_string::FormatStringHandler;
     21 using clang::analyze_format_string::LengthModifier;
     22 using clang::analyze_format_string::OptionalAmount;
     23 using clang::analyze_format_string::ConversionSpecifier;
     24 using clang::analyze_printf::PrintfSpecifier;
     25 
     26 using namespace clang;
     27 
     28 typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
     29         PrintfSpecifierResult;
     30 
     31 //===----------------------------------------------------------------------===//
     32 // Methods for parsing format strings.
     33 //===----------------------------------------------------------------------===//
     34 
     35 using analyze_format_string::ParseNonPositionAmount;
     36 
     37 static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
     38                            const char *Start, const char *&Beg, const char *E,
     39                            unsigned *argIndex) {
     40   if (argIndex) {
     41     FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
     42   } else {
     43     const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
     44                                            analyze_format_string::PrecisionPos);
     45     if (Amt.isInvalid())
     46       return true;
     47     FS.setPrecision(Amt);
     48   }
     49   return false;
     50 }
     51 
     52 static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS,
     53                            const char *FlagBeg, const char *E, bool Warn) {
     54    StringRef Flag(FlagBeg, E - FlagBeg);
     55    // Currently there is only one flag.
     56    if (Flag == "tt") {
     57      FS.setHasObjCTechnicalTerm(FlagBeg);
     58      return false;
     59    }
     60    // Handle either the case of no flag or an invalid flag.
     61    if (Warn) {
     62      if (Flag == "")
     63        H.HandleEmptyObjCModifierFlag(FlagBeg, E  - FlagBeg);
     64      else
     65        H.HandleInvalidObjCModifierFlag(FlagBeg, E  - FlagBeg);
     66    }
     67    return true;
     68 }
     69 
     70 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
     71                                                   const char *&Beg,
     72                                                   const char *E,
     73                                                   unsigned &argIndex,
     74                                                   const LangOptions &LO,
     75                                                   const TargetInfo &Target,
     76                                                   bool Warn,
     77                                                   bool isFreeBSDKPrintf) {
     78 
     79   using namespace clang::analyze_format_string;
     80   using namespace clang::analyze_printf;
     81 
     82   const char *I = Beg;
     83   const char *Start = nullptr;
     84   UpdateOnReturn <const char*> UpdateBeg(Beg, I);
     85 
     86   // Look for a '%' character that indicates the start of a format specifier.
     87   for ( ; I != E ; ++I) {
     88     char c = *I;
     89     if (c == '\0') {
     90       // Detect spurious null characters, which are likely errors.
     91       H.HandleNullChar(I);
     92       return true;
     93     }
     94     if (c == '%') {
     95       Start = I++;  // Record the start of the format specifier.
     96       break;
     97     }
     98   }
     99 
    100   // No format specifier found?
    101   if (!Start)
    102     return false;
    103 
    104   if (I == E) {
    105     // No more characters left?
    106     if (Warn)
    107       H.HandleIncompleteSpecifier(Start, E - Start);
    108     return true;
    109   }
    110 
    111   PrintfSpecifier FS;
    112   if (ParseArgPosition(H, FS, Start, I, E))
    113     return true;
    114 
    115   if (I == E) {
    116     // No more characters left?
    117     if (Warn)
    118       H.HandleIncompleteSpecifier(Start, E - Start);
    119     return true;
    120   }
    121 
    122   // Look for flags (if any).
    123   bool hasMore = true;
    124   for ( ; I != E; ++I) {
    125     switch (*I) {
    126       default: hasMore = false; break;
    127       case '\'':
    128         // FIXME: POSIX specific.  Always accept?
    129         FS.setHasThousandsGrouping(I);
    130         break;
    131       case '-': FS.setIsLeftJustified(I); break;
    132       case '+': FS.setHasPlusPrefix(I); break;
    133       case ' ': FS.setHasSpacePrefix(I); break;
    134       case '#': FS.setHasAlternativeForm(I); break;
    135       case '0': FS.setHasLeadingZeros(I); break;
    136     }
    137     if (!hasMore)
    138       break;
    139   }
    140 
    141   if (I == E) {
    142     // No more characters left?
    143     if (Warn)
    144       H.HandleIncompleteSpecifier(Start, E - Start);
    145     return true;
    146   }
    147 
    148   // Look for the field width (if any).
    149   if (ParseFieldWidth(H, FS, Start, I, E,
    150                       FS.usesPositionalArg() ? nullptr : &argIndex))
    151     return true;
    152 
    153   if (I == E) {
    154     // No more characters left?
    155     if (Warn)
    156       H.HandleIncompleteSpecifier(Start, E - Start);
    157     return true;
    158   }
    159 
    160   // Look for the precision (if any).
    161   if (*I == '.') {
    162     ++I;
    163     if (I == E) {
    164       if (Warn)
    165         H.HandleIncompleteSpecifier(Start, E - Start);
    166       return true;
    167     }
    168 
    169     if (ParsePrecision(H, FS, Start, I, E,
    170                        FS.usesPositionalArg() ? nullptr : &argIndex))
    171       return true;
    172 
    173     if (I == E) {
    174       // No more characters left?
    175       if (Warn)
    176         H.HandleIncompleteSpecifier(Start, E - Start);
    177       return true;
    178     }
    179   }
    180 
    181   // Look for the length modifier.
    182   if (ParseLengthModifier(FS, I, E, LO) && I == E) {
    183     // No more characters left?
    184     if (Warn)
    185       H.HandleIncompleteSpecifier(Start, E - Start);
    186     return true;
    187   }
    188 
    189   // Look for the Objective-C modifier flags, if any.
    190   // We parse these here, even if they don't apply to
    191   // the conversion specifier, and then emit an error
    192   // later if the conversion specifier isn't '@'.  This
    193   // enables better recovery, and we don't know if
    194   // these flags are applicable until later.
    195   const char *ObjCModifierFlagsStart = nullptr,
    196              *ObjCModifierFlagsEnd = nullptr;
    197   if (*I == '[') {
    198     ObjCModifierFlagsStart = I;
    199     ++I;
    200     auto flagStart = I;
    201     for (;; ++I) {
    202       ObjCModifierFlagsEnd = I;
    203       if (I == E) {
    204         if (Warn)
    205           H.HandleIncompleteSpecifier(Start, E - Start);
    206         return true;
    207       }
    208       // Did we find the closing ']'?
    209       if (*I == ']') {
    210         if (ParseObjCFlags(H, FS, flagStart, I, Warn))
    211           return true;
    212         ++I;
    213         break;
    214       }
    215       // There are no separators defined yet for multiple
    216       // Objective-C modifier flags.  When those are
    217       // defined, this is the place to check.
    218     }
    219   }
    220 
    221   if (*I == '\0') {
    222     // Detect spurious null characters, which are likely errors.
    223     H.HandleNullChar(I);
    224     return true;
    225   }
    226 
    227   // Finally, look for the conversion specifier.
    228   const char *conversionPosition = I++;
    229   ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
    230   switch (*conversionPosition) {
    231     default:
    232       break;
    233     // C99: 7.19.6.1 (section 8).
    234     case '%': k = ConversionSpecifier::PercentArg;   break;
    235     case 'A': k = ConversionSpecifier::AArg; break;
    236     case 'E': k = ConversionSpecifier::EArg; break;
    237     case 'F': k = ConversionSpecifier::FArg; break;
    238     case 'G': k = ConversionSpecifier::GArg; break;
    239     case 'X': k = ConversionSpecifier::XArg; break;
    240     case 'a': k = ConversionSpecifier::aArg; break;
    241     case 'c': k = ConversionSpecifier::cArg; break;
    242     case 'd': k = ConversionSpecifier::dArg; break;
    243     case 'e': k = ConversionSpecifier::eArg; break;
    244     case 'f': k = ConversionSpecifier::fArg; break;
    245     case 'g': k = ConversionSpecifier::gArg; break;
    246     case 'i': k = ConversionSpecifier::iArg; break;
    247     case 'n': k = ConversionSpecifier::nArg; break;
    248     case 'o': k = ConversionSpecifier::oArg; break;
    249     case 'p': k = ConversionSpecifier::pArg; break;
    250     case 's': k = ConversionSpecifier::sArg; break;
    251     case 'u': k = ConversionSpecifier::uArg; break;
    252     case 'x': k = ConversionSpecifier::xArg; break;
    253     // POSIX specific.
    254     case 'C': k = ConversionSpecifier::CArg; break;
    255     case 'S': k = ConversionSpecifier::SArg; break;
    256     // Objective-C.
    257     case '@': k = ConversionSpecifier::ObjCObjArg; break;
    258     // Glibc specific.
    259     case 'm': k = ConversionSpecifier::PrintErrno; break;
    260     // FreeBSD kernel specific.
    261     case 'b':
    262       if (isFreeBSDKPrintf)
    263         k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
    264       break;
    265     case 'r':
    266       if (isFreeBSDKPrintf)
    267         k = ConversionSpecifier::FreeBSDrArg; // int
    268       break;
    269     case 'y':
    270       if (isFreeBSDKPrintf)
    271         k = ConversionSpecifier::FreeBSDyArg; // int
    272       break;
    273     // Apple-specific.
    274     case 'D':
    275       if (isFreeBSDKPrintf)
    276         k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
    277       else if (Target.getTriple().isOSDarwin())
    278         k = ConversionSpecifier::DArg;
    279       break;
    280     case 'O':
    281       if (Target.getTriple().isOSDarwin())
    282         k = ConversionSpecifier::OArg;
    283       break;
    284     case 'U':
    285       if (Target.getTriple().isOSDarwin())
    286         k = ConversionSpecifier::UArg;
    287       break;
    288     // MS specific.
    289     case 'Z':
    290       if (Target.getTriple().isOSMSVCRT())
    291         k = ConversionSpecifier::ZArg;
    292   }
    293 
    294   // Check to see if we used the Objective-C modifier flags with
    295   // a conversion specifier other than '@'.
    296   if (k != ConversionSpecifier::ObjCObjArg &&
    297       k != ConversionSpecifier::InvalidSpecifier &&
    298       ObjCModifierFlagsStart) {
    299     H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
    300                                            ObjCModifierFlagsEnd + 1,
    301                                            conversionPosition);
    302     return true;
    303   }
    304 
    305   PrintfConversionSpecifier CS(conversionPosition, k);
    306   FS.setConversionSpecifier(CS);
    307   if (CS.consumesDataArgument() && !FS.usesPositionalArg())
    308     FS.setArgIndex(argIndex++);
    309   // FreeBSD kernel specific.
    310   if (k == ConversionSpecifier::FreeBSDbArg ||
    311       k == ConversionSpecifier::FreeBSDDArg)
    312     argIndex++;
    313 
    314   if (k == ConversionSpecifier::InvalidSpecifier) {
    315     // Assume the conversion takes one argument.
    316     return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start);
    317   }
    318   return PrintfSpecifierResult(Start, FS);
    319 }
    320 
    321 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
    322                                                      const char *I,
    323                                                      const char *E,
    324                                                      const LangOptions &LO,
    325                                                      const TargetInfo &Target,
    326                                                      bool isFreeBSDKPrintf) {
    327 
    328   unsigned argIndex = 0;
    329 
    330   // Keep looking for a format specifier until we have exhausted the string.
    331   while (I != E) {
    332     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
    333                                                             LO, Target, true,
    334                                                             isFreeBSDKPrintf);
    335     // Did a fail-stop error of any kind occur when parsing the specifier?
    336     // If so, don't do any more processing.
    337     if (FSR.shouldStop())
    338       return true;
    339     // Did we exhaust the string or encounter an error that
    340     // we can recover from?
    341     if (!FSR.hasValue())
    342       continue;
    343     // We have a format specifier.  Pass it to the callback.
    344     if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
    345                                  I - FSR.getStart()))
    346       return true;
    347   }
    348   assert(I == E && "Format string not exhausted");
    349   return false;
    350 }
    351 
    352 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
    353                                                             const char *E,
    354                                                             const LangOptions &LO,
    355                                                             const TargetInfo &Target) {
    356 
    357   unsigned argIndex = 0;
    358 
    359   // Keep looking for a %s format specifier until we have exhausted the string.
    360   FormatStringHandler H;
    361   while (I != E) {
    362     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
    363                                                             LO, Target, false,
    364                                                             false);
    365     // Did a fail-stop error of any kind occur when parsing the specifier?
    366     // If so, don't do any more processing.
    367     if (FSR.shouldStop())
    368       return false;
    369     // Did we exhaust the string or encounter an error that
    370     // we can recover from?
    371     if (!FSR.hasValue())
    372       continue;
    373     const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
    374     // Return true if this a %s format specifier.
    375     if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
    376       return true;
    377   }
    378   return false;
    379 }
    380 
    381 //===----------------------------------------------------------------------===//
    382 // Methods on PrintfSpecifier.
    383 //===----------------------------------------------------------------------===//
    384 
    385 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
    386                                     bool IsObjCLiteral) const {
    387   const PrintfConversionSpecifier &CS = getConversionSpecifier();
    388 
    389   if (!CS.consumesDataArgument())
    390     return ArgType::Invalid();
    391 
    392   if (CS.getKind() == ConversionSpecifier::cArg)
    393     switch (LM.getKind()) {
    394       case LengthModifier::None:
    395         return Ctx.IntTy;
    396       case LengthModifier::AsLong:
    397       case LengthModifier::AsWide:
    398         return ArgType(ArgType::WIntTy, "wint_t");
    399       case LengthModifier::AsShort:
    400         if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
    401           return Ctx.IntTy;
    402       default:
    403         return ArgType::Invalid();
    404     }
    405 
    406   if (CS.isIntArg())
    407     switch (LM.getKind()) {
    408       case LengthModifier::AsLongDouble:
    409         // GNU extension.
    410         return Ctx.LongLongTy;
    411       case LengthModifier::None:
    412         return Ctx.IntTy;
    413       case LengthModifier::AsInt32:
    414         return ArgType(Ctx.IntTy, "__int32");
    415       case LengthModifier::AsChar: return ArgType::AnyCharTy;
    416       case LengthModifier::AsShort: return Ctx.ShortTy;
    417       case LengthModifier::AsLong: return Ctx.LongTy;
    418       case LengthModifier::AsLongLong:
    419       case LengthModifier::AsQuad:
    420         return Ctx.LongLongTy;
    421       case LengthModifier::AsInt64:
    422         return ArgType(Ctx.LongLongTy, "__int64");
    423       case LengthModifier::AsIntMax:
    424         return ArgType(Ctx.getIntMaxType(), "intmax_t");
    425       case LengthModifier::AsSizeT:
    426         // FIXME: How to get the corresponding signed version of size_t?
    427         return ArgType();
    428       case LengthModifier::AsInt3264:
    429         return Ctx.getTargetInfo().getTriple().isArch64Bit()
    430                    ? ArgType(Ctx.LongLongTy, "__int64")
    431                    : ArgType(Ctx.IntTy, "__int32");
    432       case LengthModifier::AsPtrDiff:
    433         return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
    434       case LengthModifier::AsAllocate:
    435       case LengthModifier::AsMAllocate:
    436       case LengthModifier::AsWide:
    437         return ArgType::Invalid();
    438     }
    439 
    440   if (CS.isUIntArg())
    441     switch (LM.getKind()) {
    442       case LengthModifier::AsLongDouble:
    443         // GNU extension.
    444         return Ctx.UnsignedLongLongTy;
    445       case LengthModifier::None:
    446         return Ctx.UnsignedIntTy;
    447       case LengthModifier::AsInt32:
    448         return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
    449       case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
    450       case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
    451       case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
    452       case LengthModifier::AsLongLong:
    453       case LengthModifier::AsQuad:
    454         return Ctx.UnsignedLongLongTy;
    455       case LengthModifier::AsInt64:
    456         return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
    457       case LengthModifier::AsIntMax:
    458         return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
    459       case LengthModifier::AsSizeT:
    460         return ArgType(Ctx.getSizeType(), "size_t");
    461       case LengthModifier::AsInt3264:
    462         return Ctx.getTargetInfo().getTriple().isArch64Bit()
    463                    ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
    464                    : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
    465       case LengthModifier::AsPtrDiff:
    466         // FIXME: How to get the corresponding unsigned
    467         // version of ptrdiff_t?
    468         return ArgType();
    469       case LengthModifier::AsAllocate:
    470       case LengthModifier::AsMAllocate:
    471       case LengthModifier::AsWide:
    472         return ArgType::Invalid();
    473     }
    474 
    475   if (CS.isDoubleArg()) {
    476     if (LM.getKind() == LengthModifier::AsLongDouble)
    477       return Ctx.LongDoubleTy;
    478     return Ctx.DoubleTy;
    479   }
    480 
    481   if (CS.getKind() == ConversionSpecifier::nArg) {
    482     switch (LM.getKind()) {
    483       case LengthModifier::None:
    484         return ArgType::PtrTo(Ctx.IntTy);
    485       case LengthModifier::AsChar:
    486         return ArgType::PtrTo(Ctx.SignedCharTy);
    487       case LengthModifier::AsShort:
    488         return ArgType::PtrTo(Ctx.ShortTy);
    489       case LengthModifier::AsLong:
    490         return ArgType::PtrTo(Ctx.LongTy);
    491       case LengthModifier::AsLongLong:
    492       case LengthModifier::AsQuad:
    493         return ArgType::PtrTo(Ctx.LongLongTy);
    494       case LengthModifier::AsIntMax:
    495         return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
    496       case LengthModifier::AsSizeT:
    497         return ArgType(); // FIXME: ssize_t
    498       case LengthModifier::AsPtrDiff:
    499         return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
    500       case LengthModifier::AsLongDouble:
    501         return ArgType(); // FIXME: Is this a known extension?
    502       case LengthModifier::AsAllocate:
    503       case LengthModifier::AsMAllocate:
    504       case LengthModifier::AsInt32:
    505       case LengthModifier::AsInt3264:
    506       case LengthModifier::AsInt64:
    507       case LengthModifier::AsWide:
    508         return ArgType::Invalid();
    509     }
    510   }
    511 
    512   switch (CS.getKind()) {
    513     case ConversionSpecifier::sArg:
    514       if (LM.getKind() == LengthModifier::AsWideChar) {
    515         if (IsObjCLiteral)
    516           return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
    517                          "const unichar *");
    518         return ArgType(ArgType::WCStrTy, "wchar_t *");
    519       }
    520       if (LM.getKind() == LengthModifier::AsWide)
    521         return ArgType(ArgType::WCStrTy, "wchar_t *");
    522       return ArgType::CStrTy;
    523     case ConversionSpecifier::SArg:
    524       if (IsObjCLiteral)
    525         return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
    526                        "const unichar *");
    527       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
    528           LM.getKind() == LengthModifier::AsShort)
    529         return ArgType::CStrTy;
    530       return ArgType(ArgType::WCStrTy, "wchar_t *");
    531     case ConversionSpecifier::CArg:
    532       if (IsObjCLiteral)
    533         return ArgType(Ctx.UnsignedShortTy, "unichar");
    534       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
    535           LM.getKind() == LengthModifier::AsShort)
    536         return Ctx.IntTy;
    537       return ArgType(Ctx.WideCharTy, "wchar_t");
    538     case ConversionSpecifier::pArg:
    539       return ArgType::CPointerTy;
    540     case ConversionSpecifier::ObjCObjArg:
    541       return ArgType::ObjCPointerTy;
    542     default:
    543       break;
    544   }
    545 
    546   // FIXME: Handle other cases.
    547   return ArgType();
    548 }
    549 
    550 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
    551                               ASTContext &Ctx, bool IsObjCLiteral) {
    552   // %n is different from other conversion specifiers; don't try to fix it.
    553   if (CS.getKind() == ConversionSpecifier::nArg)
    554     return false;
    555 
    556   // Handle Objective-C objects first. Note that while the '%@' specifier will
    557   // not warn for structure pointer or void pointer arguments (because that's
    558   // how CoreFoundation objects are implemented), we only show a fixit for '%@'
    559   // if we know it's an object (block, id, class, or __attribute__((NSObject))).
    560   if (QT->isObjCRetainableType()) {
    561     if (!IsObjCLiteral)
    562       return false;
    563 
    564     CS.setKind(ConversionSpecifier::ObjCObjArg);
    565 
    566     // Disable irrelevant flags
    567     HasThousandsGrouping = false;
    568     HasPlusPrefix = false;
    569     HasSpacePrefix = false;
    570     HasAlternativeForm = false;
    571     HasLeadingZeroes = false;
    572     Precision.setHowSpecified(OptionalAmount::NotSpecified);
    573     LM.setKind(LengthModifier::None);
    574 
    575     return true;
    576   }
    577 
    578   // Handle strings next (char *, wchar_t *)
    579   if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
    580     CS.setKind(ConversionSpecifier::sArg);
    581 
    582     // Disable irrelevant flags
    583     HasAlternativeForm = 0;
    584     HasLeadingZeroes = 0;
    585 
    586     // Set the long length modifier for wide characters
    587     if (QT->getPointeeType()->isWideCharType())
    588       LM.setKind(LengthModifier::AsWideChar);
    589     else
    590       LM.setKind(LengthModifier::None);
    591 
    592     return true;
    593   }
    594 
    595   // If it's an enum, get its underlying type.
    596   if (const EnumType *ETy = QT->getAs<EnumType>())
    597     QT = ETy->getDecl()->getIntegerType();
    598 
    599   // We can only work with builtin types.
    600   const BuiltinType *BT = QT->getAs<BuiltinType>();
    601   if (!BT)
    602     return false;
    603 
    604   // Set length modifier
    605   switch (BT->getKind()) {
    606   case BuiltinType::Bool:
    607   case BuiltinType::WChar_U:
    608   case BuiltinType::WChar_S:
    609   case BuiltinType::Char16:
    610   case BuiltinType::Char32:
    611   case BuiltinType::UInt128:
    612   case BuiltinType::Int128:
    613   case BuiltinType::Half:
    614     // Various types which are non-trivial to correct.
    615     return false;
    616 
    617 #define SIGNED_TYPE(Id, SingletonId)
    618 #define UNSIGNED_TYPE(Id, SingletonId)
    619 #define FLOATING_TYPE(Id, SingletonId)
    620 #define BUILTIN_TYPE(Id, SingletonId) \
    621   case BuiltinType::Id:
    622 #include "clang/AST/BuiltinTypes.def"
    623     // Misc other stuff which doesn't make sense here.
    624     return false;
    625 
    626   case BuiltinType::UInt:
    627   case BuiltinType::Int:
    628   case BuiltinType::Float:
    629   case BuiltinType::Double:
    630     LM.setKind(LengthModifier::None);
    631     break;
    632 
    633   case BuiltinType::Char_U:
    634   case BuiltinType::UChar:
    635   case BuiltinType::Char_S:
    636   case BuiltinType::SChar:
    637     LM.setKind(LengthModifier::AsChar);
    638     break;
    639 
    640   case BuiltinType::Short:
    641   case BuiltinType::UShort:
    642     LM.setKind(LengthModifier::AsShort);
    643     break;
    644 
    645   case BuiltinType::Long:
    646   case BuiltinType::ULong:
    647     LM.setKind(LengthModifier::AsLong);
    648     break;
    649 
    650   case BuiltinType::LongLong:
    651   case BuiltinType::ULongLong:
    652     LM.setKind(LengthModifier::AsLongLong);
    653     break;
    654 
    655   case BuiltinType::LongDouble:
    656     LM.setKind(LengthModifier::AsLongDouble);
    657     break;
    658   }
    659 
    660   // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
    661   if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
    662     namedTypeToLengthModifier(QT, LM);
    663 
    664   // If fixing the length modifier was enough, we might be done.
    665   if (hasValidLengthModifier(Ctx.getTargetInfo())) {
    666     // If we're going to offer a fix anyway, make sure the sign matches.
    667     switch (CS.getKind()) {
    668     case ConversionSpecifier::uArg:
    669     case ConversionSpecifier::UArg:
    670       if (QT->isSignedIntegerType())
    671         CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
    672       break;
    673     case ConversionSpecifier::dArg:
    674     case ConversionSpecifier::DArg:
    675     case ConversionSpecifier::iArg:
    676       if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
    677         CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
    678       break;
    679     default:
    680       // Other specifiers do not have signed/unsigned variants.
    681       break;
    682     }
    683 
    684     const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
    685     if (ATR.isValid() && ATR.matchesType(Ctx, QT))
    686       return true;
    687   }
    688 
    689   // Set conversion specifier and disable any flags which do not apply to it.
    690   // Let typedefs to char fall through to int, as %c is silly for uint8_t.
    691   if (!isa<TypedefType>(QT) && QT->isCharType()) {
    692     CS.setKind(ConversionSpecifier::cArg);
    693     LM.setKind(LengthModifier::None);
    694     Precision.setHowSpecified(OptionalAmount::NotSpecified);
    695     HasAlternativeForm = 0;
    696     HasLeadingZeroes = 0;
    697     HasPlusPrefix = 0;
    698   }
    699   // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
    700   else if (QT->isRealFloatingType()) {
    701     CS.setKind(ConversionSpecifier::fArg);
    702   }
    703   else if (QT->isSignedIntegerType()) {
    704     CS.setKind(ConversionSpecifier::dArg);
    705     HasAlternativeForm = 0;
    706   }
    707   else if (QT->isUnsignedIntegerType()) {
    708     CS.setKind(ConversionSpecifier::uArg);
    709     HasAlternativeForm = 0;
    710     HasPlusPrefix = 0;
    711   } else {
    712     llvm_unreachable("Unexpected type");
    713   }
    714 
    715   return true;
    716 }
    717 
    718 void PrintfSpecifier::toString(raw_ostream &os) const {
    719   // Whilst some features have no defined order, we are using the order
    720   // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
    721   os << "%";
    722 
    723   // Positional args
    724   if (usesPositionalArg()) {
    725     os << getPositionalArgIndex() << "$";
    726   }
    727 
    728   // Conversion flags
    729   if (IsLeftJustified)    os << "-";
    730   if (HasPlusPrefix)      os << "+";
    731   if (HasSpacePrefix)     os << " ";
    732   if (HasAlternativeForm) os << "#";
    733   if (HasLeadingZeroes)   os << "0";
    734 
    735   // Minimum field width
    736   FieldWidth.toString(os);
    737   // Precision
    738   Precision.toString(os);
    739   // Length modifier
    740   os << LM.toString();
    741   // Conversion specifier
    742   os << CS.toString();
    743 }
    744 
    745 bool PrintfSpecifier::hasValidPlusPrefix() const {
    746   if (!HasPlusPrefix)
    747     return true;
    748 
    749   // The plus prefix only makes sense for signed conversions
    750   switch (CS.getKind()) {
    751   case ConversionSpecifier::dArg:
    752   case ConversionSpecifier::DArg:
    753   case ConversionSpecifier::iArg:
    754   case ConversionSpecifier::fArg:
    755   case ConversionSpecifier::FArg:
    756   case ConversionSpecifier::eArg:
    757   case ConversionSpecifier::EArg:
    758   case ConversionSpecifier::gArg:
    759   case ConversionSpecifier::GArg:
    760   case ConversionSpecifier::aArg:
    761   case ConversionSpecifier::AArg:
    762   case ConversionSpecifier::FreeBSDrArg:
    763   case ConversionSpecifier::FreeBSDyArg:
    764     return true;
    765 
    766   default:
    767     return false;
    768   }
    769 }
    770 
    771 bool PrintfSpecifier::hasValidAlternativeForm() const {
    772   if (!HasAlternativeForm)
    773     return true;
    774 
    775   // Alternate form flag only valid with the oxXaAeEfFgG conversions
    776   switch (CS.getKind()) {
    777   case ConversionSpecifier::oArg:
    778   case ConversionSpecifier::OArg:
    779   case ConversionSpecifier::xArg:
    780   case ConversionSpecifier::XArg:
    781   case ConversionSpecifier::aArg:
    782   case ConversionSpecifier::AArg:
    783   case ConversionSpecifier::eArg:
    784   case ConversionSpecifier::EArg:
    785   case ConversionSpecifier::fArg:
    786   case ConversionSpecifier::FArg:
    787   case ConversionSpecifier::gArg:
    788   case ConversionSpecifier::GArg:
    789   case ConversionSpecifier::FreeBSDrArg:
    790   case ConversionSpecifier::FreeBSDyArg:
    791     return true;
    792 
    793   default:
    794     return false;
    795   }
    796 }
    797 
    798 bool PrintfSpecifier::hasValidLeadingZeros() const {
    799   if (!HasLeadingZeroes)
    800     return true;
    801 
    802   // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
    803   switch (CS.getKind()) {
    804   case ConversionSpecifier::dArg:
    805   case ConversionSpecifier::DArg:
    806   case ConversionSpecifier::iArg:
    807   case ConversionSpecifier::oArg:
    808   case ConversionSpecifier::OArg:
    809   case ConversionSpecifier::uArg:
    810   case ConversionSpecifier::UArg:
    811   case ConversionSpecifier::xArg:
    812   case ConversionSpecifier::XArg:
    813   case ConversionSpecifier::aArg:
    814   case ConversionSpecifier::AArg:
    815   case ConversionSpecifier::eArg:
    816   case ConversionSpecifier::EArg:
    817   case ConversionSpecifier::fArg:
    818   case ConversionSpecifier::FArg:
    819   case ConversionSpecifier::gArg:
    820   case ConversionSpecifier::GArg:
    821   case ConversionSpecifier::FreeBSDrArg:
    822   case ConversionSpecifier::FreeBSDyArg:
    823     return true;
    824 
    825   default:
    826     return false;
    827   }
    828 }
    829 
    830 bool PrintfSpecifier::hasValidSpacePrefix() const {
    831   if (!HasSpacePrefix)
    832     return true;
    833 
    834   // The space prefix only makes sense for signed conversions
    835   switch (CS.getKind()) {
    836   case ConversionSpecifier::dArg:
    837   case ConversionSpecifier::DArg:
    838   case ConversionSpecifier::iArg:
    839   case ConversionSpecifier::fArg:
    840   case ConversionSpecifier::FArg:
    841   case ConversionSpecifier::eArg:
    842   case ConversionSpecifier::EArg:
    843   case ConversionSpecifier::gArg:
    844   case ConversionSpecifier::GArg:
    845   case ConversionSpecifier::aArg:
    846   case ConversionSpecifier::AArg:
    847   case ConversionSpecifier::FreeBSDrArg:
    848   case ConversionSpecifier::FreeBSDyArg:
    849     return true;
    850 
    851   default:
    852     return false;
    853   }
    854 }
    855 
    856 bool PrintfSpecifier::hasValidLeftJustified() const {
    857   if (!IsLeftJustified)
    858     return true;
    859 
    860   // The left justified flag is valid for all conversions except n
    861   switch (CS.getKind()) {
    862   case ConversionSpecifier::nArg:
    863     return false;
    864 
    865   default:
    866     return true;
    867   }
    868 }
    869 
    870 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
    871   if (!HasThousandsGrouping)
    872     return true;
    873 
    874   switch (CS.getKind()) {
    875     case ConversionSpecifier::dArg:
    876     case ConversionSpecifier::DArg:
    877     case ConversionSpecifier::iArg:
    878     case ConversionSpecifier::uArg:
    879     case ConversionSpecifier::UArg:
    880     case ConversionSpecifier::fArg:
    881     case ConversionSpecifier::FArg:
    882     case ConversionSpecifier::gArg:
    883     case ConversionSpecifier::GArg:
    884       return true;
    885     default:
    886       return false;
    887   }
    888 }
    889 
    890 bool PrintfSpecifier::hasValidPrecision() const {
    891   if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
    892     return true;
    893 
    894   // Precision is only valid with the diouxXaAeEfFgGs conversions
    895   switch (CS.getKind()) {
    896   case ConversionSpecifier::dArg:
    897   case ConversionSpecifier::DArg:
    898   case ConversionSpecifier::iArg:
    899   case ConversionSpecifier::oArg:
    900   case ConversionSpecifier::OArg:
    901   case ConversionSpecifier::uArg:
    902   case ConversionSpecifier::UArg:
    903   case ConversionSpecifier::xArg:
    904   case ConversionSpecifier::XArg:
    905   case ConversionSpecifier::aArg:
    906   case ConversionSpecifier::AArg:
    907   case ConversionSpecifier::eArg:
    908   case ConversionSpecifier::EArg:
    909   case ConversionSpecifier::fArg:
    910   case ConversionSpecifier::FArg:
    911   case ConversionSpecifier::gArg:
    912   case ConversionSpecifier::GArg:
    913   case ConversionSpecifier::sArg:
    914   case ConversionSpecifier::FreeBSDrArg:
    915   case ConversionSpecifier::FreeBSDyArg:
    916     return true;
    917 
    918   default:
    919     return false;
    920   }
    921 }
    922 bool PrintfSpecifier::hasValidFieldWidth() const {
    923   if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
    924       return true;
    925 
    926   // The field width is valid for all conversions except n
    927   switch (CS.getKind()) {
    928   case ConversionSpecifier::nArg:
    929     return false;
    930 
    931   default:
    932     return true;
    933   }
    934 }
    935