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     unsigned Len = I - Start;
    316     if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
    317       CS.setEndScanList(Start + Len);
    318       FS.setConversionSpecifier(CS);
    319     }
    320     // Assume the conversion takes one argument.
    321     return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
    322   }
    323   return PrintfSpecifierResult(Start, FS);
    324 }
    325 
    326 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
    327                                                      const char *I,
    328                                                      const char *E,
    329                                                      const LangOptions &LO,
    330                                                      const TargetInfo &Target,
    331                                                      bool isFreeBSDKPrintf) {
    332 
    333   unsigned argIndex = 0;
    334 
    335   // Keep looking for a format specifier until we have exhausted the string.
    336   while (I != E) {
    337     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
    338                                                             LO, Target, true,
    339                                                             isFreeBSDKPrintf);
    340     // Did a fail-stop error of any kind occur when parsing the specifier?
    341     // If so, don't do any more processing.
    342     if (FSR.shouldStop())
    343       return true;
    344     // Did we exhaust the string or encounter an error that
    345     // we can recover from?
    346     if (!FSR.hasValue())
    347       continue;
    348     // We have a format specifier.  Pass it to the callback.
    349     if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
    350                                  I - FSR.getStart()))
    351       return true;
    352   }
    353   assert(I == E && "Format string not exhausted");
    354   return false;
    355 }
    356 
    357 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
    358                                                             const char *E,
    359                                                             const LangOptions &LO,
    360                                                             const TargetInfo &Target) {
    361 
    362   unsigned argIndex = 0;
    363 
    364   // Keep looking for a %s format specifier until we have exhausted the string.
    365   FormatStringHandler H;
    366   while (I != E) {
    367     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
    368                                                             LO, Target, false,
    369                                                             false);
    370     // Did a fail-stop error of any kind occur when parsing the specifier?
    371     // If so, don't do any more processing.
    372     if (FSR.shouldStop())
    373       return false;
    374     // Did we exhaust the string or encounter an error that
    375     // we can recover from?
    376     if (!FSR.hasValue())
    377       continue;
    378     const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
    379     // Return true if this a %s format specifier.
    380     if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
    381       return true;
    382   }
    383   return false;
    384 }
    385 
    386 //===----------------------------------------------------------------------===//
    387 // Methods on PrintfSpecifier.
    388 //===----------------------------------------------------------------------===//
    389 
    390 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
    391                                     bool IsObjCLiteral) const {
    392   const PrintfConversionSpecifier &CS = getConversionSpecifier();
    393 
    394   if (!CS.consumesDataArgument())
    395     return ArgType::Invalid();
    396 
    397   if (CS.getKind() == ConversionSpecifier::cArg)
    398     switch (LM.getKind()) {
    399       case LengthModifier::None:
    400         return Ctx.IntTy;
    401       case LengthModifier::AsLong:
    402       case LengthModifier::AsWide:
    403         return ArgType(ArgType::WIntTy, "wint_t");
    404       case LengthModifier::AsShort:
    405         if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
    406           return Ctx.IntTy;
    407       default:
    408         return ArgType::Invalid();
    409     }
    410 
    411   if (CS.isIntArg())
    412     switch (LM.getKind()) {
    413       case LengthModifier::AsLongDouble:
    414         // GNU extension.
    415         return Ctx.LongLongTy;
    416       case LengthModifier::None:
    417         return Ctx.IntTy;
    418       case LengthModifier::AsInt32:
    419         return ArgType(Ctx.IntTy, "__int32");
    420       case LengthModifier::AsChar: return ArgType::AnyCharTy;
    421       case LengthModifier::AsShort: return Ctx.ShortTy;
    422       case LengthModifier::AsLong: return Ctx.LongTy;
    423       case LengthModifier::AsLongLong:
    424       case LengthModifier::AsQuad:
    425         return Ctx.LongLongTy;
    426       case LengthModifier::AsInt64:
    427         return ArgType(Ctx.LongLongTy, "__int64");
    428       case LengthModifier::AsIntMax:
    429         return ArgType(Ctx.getIntMaxType(), "intmax_t");
    430       case LengthModifier::AsSizeT:
    431         // FIXME: How to get the corresponding signed version of size_t?
    432         return ArgType();
    433       case LengthModifier::AsInt3264:
    434         return Ctx.getTargetInfo().getTriple().isArch64Bit()
    435                    ? ArgType(Ctx.LongLongTy, "__int64")
    436                    : ArgType(Ctx.IntTy, "__int32");
    437       case LengthModifier::AsPtrDiff:
    438         return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
    439       case LengthModifier::AsAllocate:
    440       case LengthModifier::AsMAllocate:
    441       case LengthModifier::AsWide:
    442         return ArgType::Invalid();
    443     }
    444 
    445   if (CS.isUIntArg())
    446     switch (LM.getKind()) {
    447       case LengthModifier::AsLongDouble:
    448         // GNU extension.
    449         return Ctx.UnsignedLongLongTy;
    450       case LengthModifier::None:
    451         return Ctx.UnsignedIntTy;
    452       case LengthModifier::AsInt32:
    453         return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
    454       case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
    455       case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
    456       case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
    457       case LengthModifier::AsLongLong:
    458       case LengthModifier::AsQuad:
    459         return Ctx.UnsignedLongLongTy;
    460       case LengthModifier::AsInt64:
    461         return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
    462       case LengthModifier::AsIntMax:
    463         return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
    464       case LengthModifier::AsSizeT:
    465         return ArgType(Ctx.getSizeType(), "size_t");
    466       case LengthModifier::AsInt3264:
    467         return Ctx.getTargetInfo().getTriple().isArch64Bit()
    468                    ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
    469                    : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
    470       case LengthModifier::AsPtrDiff:
    471         // FIXME: How to get the corresponding unsigned
    472         // version of ptrdiff_t?
    473         return ArgType();
    474       case LengthModifier::AsAllocate:
    475       case LengthModifier::AsMAllocate:
    476       case LengthModifier::AsWide:
    477         return ArgType::Invalid();
    478     }
    479 
    480   if (CS.isDoubleArg()) {
    481     if (LM.getKind() == LengthModifier::AsLongDouble)
    482       return Ctx.LongDoubleTy;
    483     return Ctx.DoubleTy;
    484   }
    485 
    486   if (CS.getKind() == ConversionSpecifier::nArg) {
    487     switch (LM.getKind()) {
    488       case LengthModifier::None:
    489         return ArgType::PtrTo(Ctx.IntTy);
    490       case LengthModifier::AsChar:
    491         return ArgType::PtrTo(Ctx.SignedCharTy);
    492       case LengthModifier::AsShort:
    493         return ArgType::PtrTo(Ctx.ShortTy);
    494       case LengthModifier::AsLong:
    495         return ArgType::PtrTo(Ctx.LongTy);
    496       case LengthModifier::AsLongLong:
    497       case LengthModifier::AsQuad:
    498         return ArgType::PtrTo(Ctx.LongLongTy);
    499       case LengthModifier::AsIntMax:
    500         return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
    501       case LengthModifier::AsSizeT:
    502         return ArgType(); // FIXME: ssize_t
    503       case LengthModifier::AsPtrDiff:
    504         return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
    505       case LengthModifier::AsLongDouble:
    506         return ArgType(); // FIXME: Is this a known extension?
    507       case LengthModifier::AsAllocate:
    508       case LengthModifier::AsMAllocate:
    509       case LengthModifier::AsInt32:
    510       case LengthModifier::AsInt3264:
    511       case LengthModifier::AsInt64:
    512       case LengthModifier::AsWide:
    513         return ArgType::Invalid();
    514     }
    515   }
    516 
    517   switch (CS.getKind()) {
    518     case ConversionSpecifier::sArg:
    519       if (LM.getKind() == LengthModifier::AsWideChar) {
    520         if (IsObjCLiteral)
    521           return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
    522                          "const unichar *");
    523         return ArgType(ArgType::WCStrTy, "wchar_t *");
    524       }
    525       if (LM.getKind() == LengthModifier::AsWide)
    526         return ArgType(ArgType::WCStrTy, "wchar_t *");
    527       return ArgType::CStrTy;
    528     case ConversionSpecifier::SArg:
    529       if (IsObjCLiteral)
    530         return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
    531                        "const unichar *");
    532       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
    533           LM.getKind() == LengthModifier::AsShort)
    534         return ArgType::CStrTy;
    535       return ArgType(ArgType::WCStrTy, "wchar_t *");
    536     case ConversionSpecifier::CArg:
    537       if (IsObjCLiteral)
    538         return ArgType(Ctx.UnsignedShortTy, "unichar");
    539       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
    540           LM.getKind() == LengthModifier::AsShort)
    541         return Ctx.IntTy;
    542       return ArgType(Ctx.WideCharTy, "wchar_t");
    543     case ConversionSpecifier::pArg:
    544       return ArgType::CPointerTy;
    545     case ConversionSpecifier::ObjCObjArg:
    546       return ArgType::ObjCPointerTy;
    547     default:
    548       break;
    549   }
    550 
    551   // FIXME: Handle other cases.
    552   return ArgType();
    553 }
    554 
    555 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
    556                               ASTContext &Ctx, bool IsObjCLiteral) {
    557   // %n is different from other conversion specifiers; don't try to fix it.
    558   if (CS.getKind() == ConversionSpecifier::nArg)
    559     return false;
    560 
    561   // Handle Objective-C objects first. Note that while the '%@' specifier will
    562   // not warn for structure pointer or void pointer arguments (because that's
    563   // how CoreFoundation objects are implemented), we only show a fixit for '%@'
    564   // if we know it's an object (block, id, class, or __attribute__((NSObject))).
    565   if (QT->isObjCRetainableType()) {
    566     if (!IsObjCLiteral)
    567       return false;
    568 
    569     CS.setKind(ConversionSpecifier::ObjCObjArg);
    570 
    571     // Disable irrelevant flags
    572     HasThousandsGrouping = false;
    573     HasPlusPrefix = false;
    574     HasSpacePrefix = false;
    575     HasAlternativeForm = false;
    576     HasLeadingZeroes = false;
    577     Precision.setHowSpecified(OptionalAmount::NotSpecified);
    578     LM.setKind(LengthModifier::None);
    579 
    580     return true;
    581   }
    582 
    583   // Handle strings next (char *, wchar_t *)
    584   if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
    585     CS.setKind(ConversionSpecifier::sArg);
    586 
    587     // Disable irrelevant flags
    588     HasAlternativeForm = 0;
    589     HasLeadingZeroes = 0;
    590 
    591     // Set the long length modifier for wide characters
    592     if (QT->getPointeeType()->isWideCharType())
    593       LM.setKind(LengthModifier::AsWideChar);
    594     else
    595       LM.setKind(LengthModifier::None);
    596 
    597     return true;
    598   }
    599 
    600   // If it's an enum, get its underlying type.
    601   if (const EnumType *ETy = QT->getAs<EnumType>())
    602     QT = ETy->getDecl()->getIntegerType();
    603 
    604   // We can only work with builtin types.
    605   const BuiltinType *BT = QT->getAs<BuiltinType>();
    606   if (!BT)
    607     return false;
    608 
    609   // Set length modifier
    610   switch (BT->getKind()) {
    611   case BuiltinType::Bool:
    612   case BuiltinType::WChar_U:
    613   case BuiltinType::WChar_S:
    614   case BuiltinType::Char16:
    615   case BuiltinType::Char32:
    616   case BuiltinType::UInt128:
    617   case BuiltinType::Int128:
    618   case BuiltinType::Half:
    619   case BuiltinType::Float128:
    620     // Various types which are non-trivial to correct.
    621     return false;
    622 
    623 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
    624   case BuiltinType::Id:
    625 #include "clang/Basic/OpenCLImageTypes.def"
    626 #define SIGNED_TYPE(Id, SingletonId)
    627 #define UNSIGNED_TYPE(Id, SingletonId)
    628 #define FLOATING_TYPE(Id, SingletonId)
    629 #define BUILTIN_TYPE(Id, SingletonId) \
    630   case BuiltinType::Id:
    631 #include "clang/AST/BuiltinTypes.def"
    632     // Misc other stuff which doesn't make sense here.
    633     return false;
    634 
    635   case BuiltinType::UInt:
    636   case BuiltinType::Int:
    637   case BuiltinType::Float:
    638   case BuiltinType::Double:
    639     LM.setKind(LengthModifier::None);
    640     break;
    641 
    642   case BuiltinType::Char_U:
    643   case BuiltinType::UChar:
    644   case BuiltinType::Char_S:
    645   case BuiltinType::SChar:
    646     LM.setKind(LengthModifier::AsChar);
    647     break;
    648 
    649   case BuiltinType::Short:
    650   case BuiltinType::UShort:
    651     LM.setKind(LengthModifier::AsShort);
    652     break;
    653 
    654   case BuiltinType::Long:
    655   case BuiltinType::ULong:
    656     LM.setKind(LengthModifier::AsLong);
    657     break;
    658 
    659   case BuiltinType::LongLong:
    660   case BuiltinType::ULongLong:
    661     LM.setKind(LengthModifier::AsLongLong);
    662     break;
    663 
    664   case BuiltinType::LongDouble:
    665     LM.setKind(LengthModifier::AsLongDouble);
    666     break;
    667   }
    668 
    669   // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
    670   if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
    671     namedTypeToLengthModifier(QT, LM);
    672 
    673   // If fixing the length modifier was enough, we might be done.
    674   if (hasValidLengthModifier(Ctx.getTargetInfo())) {
    675     // If we're going to offer a fix anyway, make sure the sign matches.
    676     switch (CS.getKind()) {
    677     case ConversionSpecifier::uArg:
    678     case ConversionSpecifier::UArg:
    679       if (QT->isSignedIntegerType())
    680         CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
    681       break;
    682     case ConversionSpecifier::dArg:
    683     case ConversionSpecifier::DArg:
    684     case ConversionSpecifier::iArg:
    685       if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
    686         CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
    687       break;
    688     default:
    689       // Other specifiers do not have signed/unsigned variants.
    690       break;
    691     }
    692 
    693     const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
    694     if (ATR.isValid() && ATR.matchesType(Ctx, QT))
    695       return true;
    696   }
    697 
    698   // Set conversion specifier and disable any flags which do not apply to it.
    699   // Let typedefs to char fall through to int, as %c is silly for uint8_t.
    700   if (!isa<TypedefType>(QT) && QT->isCharType()) {
    701     CS.setKind(ConversionSpecifier::cArg);
    702     LM.setKind(LengthModifier::None);
    703     Precision.setHowSpecified(OptionalAmount::NotSpecified);
    704     HasAlternativeForm = 0;
    705     HasLeadingZeroes = 0;
    706     HasPlusPrefix = 0;
    707   }
    708   // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
    709   else if (QT->isRealFloatingType()) {
    710     CS.setKind(ConversionSpecifier::fArg);
    711   }
    712   else if (QT->isSignedIntegerType()) {
    713     CS.setKind(ConversionSpecifier::dArg);
    714     HasAlternativeForm = 0;
    715   }
    716   else if (QT->isUnsignedIntegerType()) {
    717     CS.setKind(ConversionSpecifier::uArg);
    718     HasAlternativeForm = 0;
    719     HasPlusPrefix = 0;
    720   } else {
    721     llvm_unreachable("Unexpected type");
    722   }
    723 
    724   return true;
    725 }
    726 
    727 void PrintfSpecifier::toString(raw_ostream &os) const {
    728   // Whilst some features have no defined order, we are using the order
    729   // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
    730   os << "%";
    731 
    732   // Positional args
    733   if (usesPositionalArg()) {
    734     os << getPositionalArgIndex() << "$";
    735   }
    736 
    737   // Conversion flags
    738   if (IsLeftJustified)    os << "-";
    739   if (HasPlusPrefix)      os << "+";
    740   if (HasSpacePrefix)     os << " ";
    741   if (HasAlternativeForm) os << "#";
    742   if (HasLeadingZeroes)   os << "0";
    743 
    744   // Minimum field width
    745   FieldWidth.toString(os);
    746   // Precision
    747   Precision.toString(os);
    748   // Length modifier
    749   os << LM.toString();
    750   // Conversion specifier
    751   os << CS.toString();
    752 }
    753 
    754 bool PrintfSpecifier::hasValidPlusPrefix() const {
    755   if (!HasPlusPrefix)
    756     return true;
    757 
    758   // The plus prefix only makes sense for signed conversions
    759   switch (CS.getKind()) {
    760   case ConversionSpecifier::dArg:
    761   case ConversionSpecifier::DArg:
    762   case ConversionSpecifier::iArg:
    763   case ConversionSpecifier::fArg:
    764   case ConversionSpecifier::FArg:
    765   case ConversionSpecifier::eArg:
    766   case ConversionSpecifier::EArg:
    767   case ConversionSpecifier::gArg:
    768   case ConversionSpecifier::GArg:
    769   case ConversionSpecifier::aArg:
    770   case ConversionSpecifier::AArg:
    771   case ConversionSpecifier::FreeBSDrArg:
    772   case ConversionSpecifier::FreeBSDyArg:
    773     return true;
    774 
    775   default:
    776     return false;
    777   }
    778 }
    779 
    780 bool PrintfSpecifier::hasValidAlternativeForm() const {
    781   if (!HasAlternativeForm)
    782     return true;
    783 
    784   // Alternate form flag only valid with the oxXaAeEfFgG conversions
    785   switch (CS.getKind()) {
    786   case ConversionSpecifier::oArg:
    787   case ConversionSpecifier::OArg:
    788   case ConversionSpecifier::xArg:
    789   case ConversionSpecifier::XArg:
    790   case ConversionSpecifier::aArg:
    791   case ConversionSpecifier::AArg:
    792   case ConversionSpecifier::eArg:
    793   case ConversionSpecifier::EArg:
    794   case ConversionSpecifier::fArg:
    795   case ConversionSpecifier::FArg:
    796   case ConversionSpecifier::gArg:
    797   case ConversionSpecifier::GArg:
    798   case ConversionSpecifier::FreeBSDrArg:
    799   case ConversionSpecifier::FreeBSDyArg:
    800     return true;
    801 
    802   default:
    803     return false;
    804   }
    805 }
    806 
    807 bool PrintfSpecifier::hasValidLeadingZeros() const {
    808   if (!HasLeadingZeroes)
    809     return true;
    810 
    811   // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
    812   switch (CS.getKind()) {
    813   case ConversionSpecifier::dArg:
    814   case ConversionSpecifier::DArg:
    815   case ConversionSpecifier::iArg:
    816   case ConversionSpecifier::oArg:
    817   case ConversionSpecifier::OArg:
    818   case ConversionSpecifier::uArg:
    819   case ConversionSpecifier::UArg:
    820   case ConversionSpecifier::xArg:
    821   case ConversionSpecifier::XArg:
    822   case ConversionSpecifier::aArg:
    823   case ConversionSpecifier::AArg:
    824   case ConversionSpecifier::eArg:
    825   case ConversionSpecifier::EArg:
    826   case ConversionSpecifier::fArg:
    827   case ConversionSpecifier::FArg:
    828   case ConversionSpecifier::gArg:
    829   case ConversionSpecifier::GArg:
    830   case ConversionSpecifier::FreeBSDrArg:
    831   case ConversionSpecifier::FreeBSDyArg:
    832     return true;
    833 
    834   default:
    835     return false;
    836   }
    837 }
    838 
    839 bool PrintfSpecifier::hasValidSpacePrefix() const {
    840   if (!HasSpacePrefix)
    841     return true;
    842 
    843   // The space prefix only makes sense for signed conversions
    844   switch (CS.getKind()) {
    845   case ConversionSpecifier::dArg:
    846   case ConversionSpecifier::DArg:
    847   case ConversionSpecifier::iArg:
    848   case ConversionSpecifier::fArg:
    849   case ConversionSpecifier::FArg:
    850   case ConversionSpecifier::eArg:
    851   case ConversionSpecifier::EArg:
    852   case ConversionSpecifier::gArg:
    853   case ConversionSpecifier::GArg:
    854   case ConversionSpecifier::aArg:
    855   case ConversionSpecifier::AArg:
    856   case ConversionSpecifier::FreeBSDrArg:
    857   case ConversionSpecifier::FreeBSDyArg:
    858     return true;
    859 
    860   default:
    861     return false;
    862   }
    863 }
    864 
    865 bool PrintfSpecifier::hasValidLeftJustified() const {
    866   if (!IsLeftJustified)
    867     return true;
    868 
    869   // The left justified flag is valid for all conversions except n
    870   switch (CS.getKind()) {
    871   case ConversionSpecifier::nArg:
    872     return false;
    873 
    874   default:
    875     return true;
    876   }
    877 }
    878 
    879 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
    880   if (!HasThousandsGrouping)
    881     return true;
    882 
    883   switch (CS.getKind()) {
    884     case ConversionSpecifier::dArg:
    885     case ConversionSpecifier::DArg:
    886     case ConversionSpecifier::iArg:
    887     case ConversionSpecifier::uArg:
    888     case ConversionSpecifier::UArg:
    889     case ConversionSpecifier::fArg:
    890     case ConversionSpecifier::FArg:
    891     case ConversionSpecifier::gArg:
    892     case ConversionSpecifier::GArg:
    893       return true;
    894     default:
    895       return false;
    896   }
    897 }
    898 
    899 bool PrintfSpecifier::hasValidPrecision() const {
    900   if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
    901     return true;
    902 
    903   // Precision is only valid with the diouxXaAeEfFgGs conversions
    904   switch (CS.getKind()) {
    905   case ConversionSpecifier::dArg:
    906   case ConversionSpecifier::DArg:
    907   case ConversionSpecifier::iArg:
    908   case ConversionSpecifier::oArg:
    909   case ConversionSpecifier::OArg:
    910   case ConversionSpecifier::uArg:
    911   case ConversionSpecifier::UArg:
    912   case ConversionSpecifier::xArg:
    913   case ConversionSpecifier::XArg:
    914   case ConversionSpecifier::aArg:
    915   case ConversionSpecifier::AArg:
    916   case ConversionSpecifier::eArg:
    917   case ConversionSpecifier::EArg:
    918   case ConversionSpecifier::fArg:
    919   case ConversionSpecifier::FArg:
    920   case ConversionSpecifier::gArg:
    921   case ConversionSpecifier::GArg:
    922   case ConversionSpecifier::sArg:
    923   case ConversionSpecifier::FreeBSDrArg:
    924   case ConversionSpecifier::FreeBSDyArg:
    925     return true;
    926 
    927   default:
    928     return false;
    929   }
    930 }
    931 bool PrintfSpecifier::hasValidFieldWidth() const {
    932   if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
    933       return true;
    934 
    935   // The field width is valid for all conversions except n
    936   switch (CS.getKind()) {
    937   case ConversionSpecifier::nArg:
    938     return false;
    939 
    940   default:
    941     return true;
    942   }
    943 }
    944