Home | History | Annotate | Download | only in Analysis
      1 // FormatString.cpp - Common stuff for handling printf/scanf formats -*- 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 // Shared details for processing format strings of printf and scanf
     11 // (and friends).
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "FormatStringParsing.h"
     16 #include "clang/Basic/LangOptions.h"
     17 #include "clang/Basic/TargetInfo.h"
     18 #include "llvm/Support/ConvertUTF.h"
     19 
     20 using clang::analyze_format_string::ArgType;
     21 using clang::analyze_format_string::FormatStringHandler;
     22 using clang::analyze_format_string::FormatSpecifier;
     23 using clang::analyze_format_string::LengthModifier;
     24 using clang::analyze_format_string::OptionalAmount;
     25 using clang::analyze_format_string::PositionContext;
     26 using clang::analyze_format_string::ConversionSpecifier;
     27 using namespace clang;
     28 
     29 // Key function to FormatStringHandler.
     30 FormatStringHandler::~FormatStringHandler() {}
     31 
     32 //===----------------------------------------------------------------------===//
     33 // Functions for parsing format strings components in both printf and
     34 // scanf format strings.
     35 //===----------------------------------------------------------------------===//
     36 
     37 OptionalAmount
     38 clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
     39   const char *I = Beg;
     40   UpdateOnReturn <const char*> UpdateBeg(Beg, I);
     41 
     42   unsigned accumulator = 0;
     43   bool hasDigits = false;
     44 
     45   for ( ; I != E; ++I) {
     46     char c = *I;
     47     if (c >= '0' && c <= '9') {
     48       hasDigits = true;
     49       accumulator = (accumulator * 10) + (c - '0');
     50       continue;
     51     }
     52 
     53     if (hasDigits)
     54       return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
     55           false);
     56 
     57     break;
     58   }
     59 
     60   return OptionalAmount();
     61 }
     62 
     63 OptionalAmount
     64 clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
     65                                                      const char *E,
     66                                                      unsigned &argIndex) {
     67   if (*Beg == '*') {
     68     ++Beg;
     69     return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
     70   }
     71 
     72   return ParseAmount(Beg, E);
     73 }
     74 
     75 OptionalAmount
     76 clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H,
     77                                                   const char *Start,
     78                                                   const char *&Beg,
     79                                                   const char *E,
     80                                                   PositionContext p) {
     81   if (*Beg == '*') {
     82     const char *I = Beg + 1;
     83     const OptionalAmount &Amt = ParseAmount(I, E);
     84 
     85     if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
     86       H.HandleInvalidPosition(Beg, I - Beg, p);
     87       return OptionalAmount(false);
     88     }
     89 
     90     if (I == E) {
     91       // No more characters left?
     92       H.HandleIncompleteSpecifier(Start, E - Start);
     93       return OptionalAmount(false);
     94     }
     95 
     96     assert(Amt.getHowSpecified() == OptionalAmount::Constant);
     97 
     98     if (*I == '$') {
     99       // Handle positional arguments
    100 
    101       // Special case: '*0$', since this is an easy mistake.
    102       if (Amt.getConstantAmount() == 0) {
    103         H.HandleZeroPosition(Beg, I - Beg + 1);
    104         return OptionalAmount(false);
    105       }
    106 
    107       const char *Tmp = Beg;
    108       Beg = ++I;
    109 
    110       return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
    111                             Tmp, 0, true);
    112     }
    113 
    114     H.HandleInvalidPosition(Beg, I - Beg, p);
    115     return OptionalAmount(false);
    116   }
    117 
    118   return ParseAmount(Beg, E);
    119 }
    120 
    121 
    122 bool
    123 clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
    124                                               FormatSpecifier &CS,
    125                                               const char *Start,
    126                                               const char *&Beg, const char *E,
    127                                               unsigned *argIndex) {
    128   // FIXME: Support negative field widths.
    129   if (argIndex) {
    130     CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
    131   }
    132   else {
    133     const OptionalAmount Amt =
    134       ParsePositionAmount(H, Start, Beg, E,
    135                           analyze_format_string::FieldWidthPos);
    136 
    137     if (Amt.isInvalid())
    138       return true;
    139     CS.setFieldWidth(Amt);
    140   }
    141   return false;
    142 }
    143 
    144 bool
    145 clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
    146                                                FormatSpecifier &FS,
    147                                                const char *Start,
    148                                                const char *&Beg,
    149                                                const char *E) {
    150   const char *I = Beg;
    151 
    152   const OptionalAmount &Amt = ParseAmount(I, E);
    153 
    154   if (I == E) {
    155     // No more characters left?
    156     H.HandleIncompleteSpecifier(Start, E - Start);
    157     return true;
    158   }
    159 
    160   if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
    161     // Warn that positional arguments are non-standard.
    162     H.HandlePosition(Start, I - Start);
    163 
    164     // Special case: '%0$', since this is an easy mistake.
    165     if (Amt.getConstantAmount() == 0) {
    166       H.HandleZeroPosition(Start, I - Start);
    167       return true;
    168     }
    169 
    170     FS.setArgIndex(Amt.getConstantAmount() - 1);
    171     FS.setUsesPositionalArg();
    172     // Update the caller's pointer if we decided to consume
    173     // these characters.
    174     Beg = I;
    175     return false;
    176   }
    177 
    178   return false;
    179 }
    180 
    181 bool
    182 clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
    183                                                   const char *&I,
    184                                                   const char *E,
    185                                                   const LangOptions &LO,
    186                                                   bool IsScanf) {
    187   LengthModifier::Kind lmKind = LengthModifier::None;
    188   const char *lmPosition = I;
    189   switch (*I) {
    190     default:
    191       return false;
    192     case 'h':
    193       ++I;
    194       if (I != E && *I == 'h') {
    195         ++I;
    196         lmKind = LengthModifier::AsChar;
    197       } else {
    198         lmKind = LengthModifier::AsShort;
    199       }
    200       break;
    201     case 'l':
    202       ++I;
    203       if (I != E && *I == 'l') {
    204         ++I;
    205         lmKind = LengthModifier::AsLongLong;
    206       } else {
    207         lmKind = LengthModifier::AsLong;
    208       }
    209       break;
    210     case 'j': lmKind = LengthModifier::AsIntMax;     ++I; break;
    211     case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
    212     case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
    213     case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
    214     case 'q': lmKind = LengthModifier::AsQuad;       ++I; break;
    215     case 'a':
    216       if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
    217         // For scanf in C90, look at the next character to see if this should
    218         // be parsed as the GNU extension 'a' length modifier. If not, this
    219         // will be parsed as a conversion specifier.
    220         ++I;
    221         if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
    222           lmKind = LengthModifier::AsAllocate;
    223           break;
    224         }
    225         --I;
    226       }
    227       return false;
    228     case 'm':
    229       if (IsScanf) {
    230         lmKind = LengthModifier::AsMAllocate;
    231         ++I;
    232         break;
    233       }
    234       return false;
    235     // printf: AsInt64, AsInt32, AsInt3264
    236     // scanf:  AsInt64
    237     case 'I':
    238       if (I + 1 != E && I + 2 != E) {
    239         if (I[1] == '6' && I[2] == '4') {
    240           I += 3;
    241           lmKind = LengthModifier::AsInt64;
    242           break;
    243         }
    244         if (IsScanf)
    245           return false;
    246 
    247         if (I[1] == '3' && I[2] == '2') {
    248           I += 3;
    249           lmKind = LengthModifier::AsInt32;
    250           break;
    251         }
    252       }
    253       ++I;
    254       lmKind = LengthModifier::AsInt3264;
    255       break;
    256     case 'w':
    257       lmKind = LengthModifier::AsWide; ++I; break;
    258   }
    259   LengthModifier lm(lmPosition, lmKind);
    260   FS.setLengthModifier(lm);
    261   return true;
    262 }
    263 
    264 bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
    265     const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
    266   if (SpecifierBegin + 1 >= FmtStrEnd)
    267     return false;
    268 
    269   const UTF8 *SB = reinterpret_cast<const UTF8 *>(SpecifierBegin + 1);
    270   const UTF8 *SE = reinterpret_cast<const UTF8 *>(FmtStrEnd);
    271   const char FirstByte = *SB;
    272 
    273   // If the invalid specifier is a multibyte UTF-8 string, return the
    274   // total length accordingly so that the conversion specifier can be
    275   // properly updated to reflect a complete UTF-8 specifier.
    276   unsigned NumBytes = getNumBytesForUTF8(FirstByte);
    277   if (NumBytes == 1)
    278     return false;
    279   if (SB + NumBytes > SE)
    280     return false;
    281 
    282   Len = NumBytes + 1;
    283   return true;
    284 }
    285 
    286 //===----------------------------------------------------------------------===//
    287 // Methods on ArgType.
    288 //===----------------------------------------------------------------------===//
    289 
    290 clang::analyze_format_string::ArgType::MatchKind
    291 ArgType::matchesType(ASTContext &C, QualType argTy) const {
    292   if (Ptr) {
    293     // It has to be a pointer.
    294     const PointerType *PT = argTy->getAs<PointerType>();
    295     if (!PT)
    296       return NoMatch;
    297 
    298     // We cannot write through a const qualified pointer.
    299     if (PT->getPointeeType().isConstQualified())
    300       return NoMatch;
    301 
    302     argTy = PT->getPointeeType();
    303   }
    304 
    305   switch (K) {
    306     case InvalidTy:
    307       llvm_unreachable("ArgType must be valid");
    308 
    309     case UnknownTy:
    310       return Match;
    311 
    312     case AnyCharTy: {
    313       if (const EnumType *ETy = argTy->getAs<EnumType>())
    314         argTy = ETy->getDecl()->getIntegerType();
    315 
    316       if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
    317         switch (BT->getKind()) {
    318           default:
    319             break;
    320           case BuiltinType::Char_S:
    321           case BuiltinType::SChar:
    322           case BuiltinType::UChar:
    323           case BuiltinType::Char_U:
    324             return Match;
    325         }
    326       return NoMatch;
    327     }
    328 
    329     case SpecificTy: {
    330       if (const EnumType *ETy = argTy->getAs<EnumType>())
    331         argTy = ETy->getDecl()->getIntegerType();
    332       argTy = C.getCanonicalType(argTy).getUnqualifiedType();
    333 
    334       if (T == argTy)
    335         return Match;
    336       // Check for "compatible types".
    337       if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
    338         switch (BT->getKind()) {
    339           default:
    340             break;
    341           case BuiltinType::Char_S:
    342           case BuiltinType::SChar:
    343           case BuiltinType::Char_U:
    344           case BuiltinType::UChar:
    345             return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match
    346                                                                 : NoMatch;
    347           case BuiltinType::Short:
    348             return T == C.UnsignedShortTy ? Match : NoMatch;
    349           case BuiltinType::UShort:
    350             return T == C.ShortTy ? Match : NoMatch;
    351           case BuiltinType::Int:
    352             return T == C.UnsignedIntTy ? Match : NoMatch;
    353           case BuiltinType::UInt:
    354             return T == C.IntTy ? Match : NoMatch;
    355           case BuiltinType::Long:
    356             return T == C.UnsignedLongTy ? Match : NoMatch;
    357           case BuiltinType::ULong:
    358             return T == C.LongTy ? Match : NoMatch;
    359           case BuiltinType::LongLong:
    360             return T == C.UnsignedLongLongTy ? Match : NoMatch;
    361           case BuiltinType::ULongLong:
    362             return T == C.LongLongTy ? Match : NoMatch;
    363         }
    364       return NoMatch;
    365     }
    366 
    367     case CStrTy: {
    368       const PointerType *PT = argTy->getAs<PointerType>();
    369       if (!PT)
    370         return NoMatch;
    371       QualType pointeeTy = PT->getPointeeType();
    372       if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
    373         switch (BT->getKind()) {
    374           case BuiltinType::Void:
    375           case BuiltinType::Char_U:
    376           case BuiltinType::UChar:
    377           case BuiltinType::Char_S:
    378           case BuiltinType::SChar:
    379             return Match;
    380           default:
    381             break;
    382         }
    383 
    384       return NoMatch;
    385     }
    386 
    387     case WCStrTy: {
    388       const PointerType *PT = argTy->getAs<PointerType>();
    389       if (!PT)
    390         return NoMatch;
    391       QualType pointeeTy =
    392         C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
    393       return pointeeTy == C.getWideCharType() ? Match : NoMatch;
    394     }
    395 
    396     case WIntTy: {
    397 
    398       QualType PromoArg =
    399         argTy->isPromotableIntegerType()
    400           ? C.getPromotedIntegerType(argTy) : argTy;
    401 
    402       QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
    403       PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
    404 
    405       // If the promoted argument is the corresponding signed type of the
    406       // wint_t type, then it should match.
    407       if (PromoArg->hasSignedIntegerRepresentation() &&
    408           C.getCorrespondingUnsignedType(PromoArg) == WInt)
    409         return Match;
    410 
    411       return WInt == PromoArg ? Match : NoMatch;
    412     }
    413 
    414     case CPointerTy:
    415       if (argTy->isVoidPointerType()) {
    416         return Match;
    417       } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
    418             argTy->isBlockPointerType() || argTy->isNullPtrType()) {
    419         return NoMatchPedantic;
    420       } else {
    421         return NoMatch;
    422       }
    423 
    424     case ObjCPointerTy: {
    425       if (argTy->getAs<ObjCObjectPointerType>() ||
    426           argTy->getAs<BlockPointerType>())
    427         return Match;
    428 
    429       // Handle implicit toll-free bridging.
    430       if (const PointerType *PT = argTy->getAs<PointerType>()) {
    431         // Things such as CFTypeRef are really just opaque pointers
    432         // to C structs representing CF types that can often be bridged
    433         // to Objective-C objects.  Since the compiler doesn't know which
    434         // structs can be toll-free bridged, we just accept them all.
    435         QualType pointee = PT->getPointeeType();
    436         if (pointee->getAsStructureType() || pointee->isVoidType())
    437           return Match;
    438       }
    439       return NoMatch;
    440     }
    441   }
    442 
    443   llvm_unreachable("Invalid ArgType Kind!");
    444 }
    445 
    446 QualType ArgType::getRepresentativeType(ASTContext &C) const {
    447   QualType Res;
    448   switch (K) {
    449     case InvalidTy:
    450       llvm_unreachable("No representative type for Invalid ArgType");
    451     case UnknownTy:
    452       llvm_unreachable("No representative type for Unknown ArgType");
    453     case AnyCharTy:
    454       Res = C.CharTy;
    455       break;
    456     case SpecificTy:
    457       Res = T;
    458       break;
    459     case CStrTy:
    460       Res = C.getPointerType(C.CharTy);
    461       break;
    462     case WCStrTy:
    463       Res = C.getPointerType(C.getWideCharType());
    464       break;
    465     case ObjCPointerTy:
    466       Res = C.ObjCBuiltinIdTy;
    467       break;
    468     case CPointerTy:
    469       Res = C.VoidPtrTy;
    470       break;
    471     case WIntTy: {
    472       Res = C.getWIntType();
    473       break;
    474     }
    475   }
    476 
    477   if (Ptr)
    478     Res = C.getPointerType(Res);
    479   return Res;
    480 }
    481 
    482 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
    483   std::string S = getRepresentativeType(C).getAsString();
    484 
    485   std::string Alias;
    486   if (Name) {
    487     // Use a specific name for this type, e.g. "size_t".
    488     Alias = Name;
    489     if (Ptr) {
    490       // If ArgType is actually a pointer to T, append an asterisk.
    491       Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
    492     }
    493     // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
    494     if (S == Alias)
    495       Alias.clear();
    496   }
    497 
    498   if (!Alias.empty())
    499     return std::string("'") + Alias + "' (aka '" + S + "')";
    500   return std::string("'") + S + "'";
    501 }
    502 
    503 
    504 //===----------------------------------------------------------------------===//
    505 // Methods on OptionalAmount.
    506 //===----------------------------------------------------------------------===//
    507 
    508 ArgType
    509 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
    510   return Ctx.IntTy;
    511 }
    512 
    513 //===----------------------------------------------------------------------===//
    514 // Methods on LengthModifier.
    515 //===----------------------------------------------------------------------===//
    516 
    517 const char *
    518 analyze_format_string::LengthModifier::toString() const {
    519   switch (kind) {
    520   case AsChar:
    521     return "hh";
    522   case AsShort:
    523     return "h";
    524   case AsLong: // or AsWideChar
    525     return "l";
    526   case AsLongLong:
    527     return "ll";
    528   case AsQuad:
    529     return "q";
    530   case AsIntMax:
    531     return "j";
    532   case AsSizeT:
    533     return "z";
    534   case AsPtrDiff:
    535     return "t";
    536   case AsInt32:
    537     return "I32";
    538   case AsInt3264:
    539     return "I";
    540   case AsInt64:
    541     return "I64";
    542   case AsLongDouble:
    543     return "L";
    544   case AsAllocate:
    545     return "a";
    546   case AsMAllocate:
    547     return "m";
    548   case AsWide:
    549     return "w";
    550   case None:
    551     return "";
    552   }
    553   return nullptr;
    554 }
    555 
    556 //===----------------------------------------------------------------------===//
    557 // Methods on ConversionSpecifier.
    558 //===----------------------------------------------------------------------===//
    559 
    560 const char *ConversionSpecifier::toString() const {
    561   switch (kind) {
    562   case dArg: return "d";
    563   case DArg: return "D";
    564   case iArg: return "i";
    565   case oArg: return "o";
    566   case OArg: return "O";
    567   case uArg: return "u";
    568   case UArg: return "U";
    569   case xArg: return "x";
    570   case XArg: return "X";
    571   case fArg: return "f";
    572   case FArg: return "F";
    573   case eArg: return "e";
    574   case EArg: return "E";
    575   case gArg: return "g";
    576   case GArg: return "G";
    577   case aArg: return "a";
    578   case AArg: return "A";
    579   case cArg: return "c";
    580   case sArg: return "s";
    581   case pArg: return "p";
    582   case nArg: return "n";
    583   case PercentArg:  return "%";
    584   case ScanListArg: return "[";
    585   case InvalidSpecifier: return nullptr;
    586 
    587   // POSIX unicode extensions.
    588   case CArg: return "C";
    589   case SArg: return "S";
    590 
    591   // Objective-C specific specifiers.
    592   case ObjCObjArg: return "@";
    593 
    594   // FreeBSD kernel specific specifiers.
    595   case FreeBSDbArg: return "b";
    596   case FreeBSDDArg: return "D";
    597   case FreeBSDrArg: return "r";
    598   case FreeBSDyArg: return "y";
    599 
    600   // GlibC specific specifiers.
    601   case PrintErrno: return "m";
    602 
    603   // MS specific specifiers.
    604   case ZArg: return "Z";
    605   }
    606   return nullptr;
    607 }
    608 
    609 Optional<ConversionSpecifier>
    610 ConversionSpecifier::getStandardSpecifier() const {
    611   ConversionSpecifier::Kind NewKind;
    612 
    613   switch (getKind()) {
    614   default:
    615     return None;
    616   case DArg:
    617     NewKind = dArg;
    618     break;
    619   case UArg:
    620     NewKind = uArg;
    621     break;
    622   case OArg:
    623     NewKind = oArg;
    624     break;
    625   }
    626 
    627   ConversionSpecifier FixedCS(*this);
    628   FixedCS.setKind(NewKind);
    629   return FixedCS;
    630 }
    631 
    632 //===----------------------------------------------------------------------===//
    633 // Methods on OptionalAmount.
    634 //===----------------------------------------------------------------------===//
    635 
    636 void OptionalAmount::toString(raw_ostream &os) const {
    637   switch (hs) {
    638   case Invalid:
    639   case NotSpecified:
    640     return;
    641   case Arg:
    642     if (UsesDotPrefix)
    643         os << ".";
    644     if (usesPositionalArg())
    645       os << "*" << getPositionalArgIndex() << "$";
    646     else
    647       os << "*";
    648     break;
    649   case Constant:
    650     if (UsesDotPrefix)
    651         os << ".";
    652     os << amt;
    653     break;
    654   }
    655 }
    656 
    657 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
    658   switch (LM.getKind()) {
    659     case LengthModifier::None:
    660       return true;
    661 
    662     // Handle most integer flags
    663     case LengthModifier::AsShort:
    664       if (Target.getTriple().isOSMSVCRT()) {
    665         switch (CS.getKind()) {
    666           case ConversionSpecifier::cArg:
    667           case ConversionSpecifier::CArg:
    668           case ConversionSpecifier::sArg:
    669           case ConversionSpecifier::SArg:
    670           case ConversionSpecifier::ZArg:
    671             return true;
    672           default:
    673             break;
    674         }
    675       }
    676       // Fall through.
    677     case LengthModifier::AsChar:
    678     case LengthModifier::AsLongLong:
    679     case LengthModifier::AsQuad:
    680     case LengthModifier::AsIntMax:
    681     case LengthModifier::AsSizeT:
    682     case LengthModifier::AsPtrDiff:
    683       switch (CS.getKind()) {
    684         case ConversionSpecifier::dArg:
    685         case ConversionSpecifier::DArg:
    686         case ConversionSpecifier::iArg:
    687         case ConversionSpecifier::oArg:
    688         case ConversionSpecifier::OArg:
    689         case ConversionSpecifier::uArg:
    690         case ConversionSpecifier::UArg:
    691         case ConversionSpecifier::xArg:
    692         case ConversionSpecifier::XArg:
    693         case ConversionSpecifier::nArg:
    694           return true;
    695         case ConversionSpecifier::FreeBSDrArg:
    696         case ConversionSpecifier::FreeBSDyArg:
    697           return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
    698         default:
    699           return false;
    700       }
    701 
    702     // Handle 'l' flag
    703     case LengthModifier::AsLong: // or AsWideChar
    704       switch (CS.getKind()) {
    705         case ConversionSpecifier::dArg:
    706         case ConversionSpecifier::DArg:
    707         case ConversionSpecifier::iArg:
    708         case ConversionSpecifier::oArg:
    709         case ConversionSpecifier::OArg:
    710         case ConversionSpecifier::uArg:
    711         case ConversionSpecifier::UArg:
    712         case ConversionSpecifier::xArg:
    713         case ConversionSpecifier::XArg:
    714         case ConversionSpecifier::aArg:
    715         case ConversionSpecifier::AArg:
    716         case ConversionSpecifier::fArg:
    717         case ConversionSpecifier::FArg:
    718         case ConversionSpecifier::eArg:
    719         case ConversionSpecifier::EArg:
    720         case ConversionSpecifier::gArg:
    721         case ConversionSpecifier::GArg:
    722         case ConversionSpecifier::nArg:
    723         case ConversionSpecifier::cArg:
    724         case ConversionSpecifier::sArg:
    725         case ConversionSpecifier::ScanListArg:
    726         case ConversionSpecifier::ZArg:
    727           return true;
    728         case ConversionSpecifier::FreeBSDrArg:
    729         case ConversionSpecifier::FreeBSDyArg:
    730           return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
    731         default:
    732           return false;
    733       }
    734 
    735     case LengthModifier::AsLongDouble:
    736       switch (CS.getKind()) {
    737         case ConversionSpecifier::aArg:
    738         case ConversionSpecifier::AArg:
    739         case ConversionSpecifier::fArg:
    740         case ConversionSpecifier::FArg:
    741         case ConversionSpecifier::eArg:
    742         case ConversionSpecifier::EArg:
    743         case ConversionSpecifier::gArg:
    744         case ConversionSpecifier::GArg:
    745           return true;
    746         // GNU libc extension.
    747         case ConversionSpecifier::dArg:
    748         case ConversionSpecifier::iArg:
    749         case ConversionSpecifier::oArg:
    750         case ConversionSpecifier::uArg:
    751         case ConversionSpecifier::xArg:
    752         case ConversionSpecifier::XArg:
    753           return !Target.getTriple().isOSDarwin() &&
    754                  !Target.getTriple().isOSWindows();
    755         default:
    756           return false;
    757       }
    758 
    759     case LengthModifier::AsAllocate:
    760       switch (CS.getKind()) {
    761         case ConversionSpecifier::sArg:
    762         case ConversionSpecifier::SArg:
    763         case ConversionSpecifier::ScanListArg:
    764           return true;
    765         default:
    766           return false;
    767       }
    768 
    769     case LengthModifier::AsMAllocate:
    770       switch (CS.getKind()) {
    771         case ConversionSpecifier::cArg:
    772         case ConversionSpecifier::CArg:
    773         case ConversionSpecifier::sArg:
    774         case ConversionSpecifier::SArg:
    775         case ConversionSpecifier::ScanListArg:
    776           return true;
    777         default:
    778           return false;
    779       }
    780     case LengthModifier::AsInt32:
    781     case LengthModifier::AsInt3264:
    782     case LengthModifier::AsInt64:
    783       switch (CS.getKind()) {
    784         case ConversionSpecifier::dArg:
    785         case ConversionSpecifier::iArg:
    786         case ConversionSpecifier::oArg:
    787         case ConversionSpecifier::uArg:
    788         case ConversionSpecifier::xArg:
    789         case ConversionSpecifier::XArg:
    790           return Target.getTriple().isOSMSVCRT();
    791         default:
    792           return false;
    793       }
    794     case LengthModifier::AsWide:
    795       switch (CS.getKind()) {
    796         case ConversionSpecifier::cArg:
    797         case ConversionSpecifier::CArg:
    798         case ConversionSpecifier::sArg:
    799         case ConversionSpecifier::SArg:
    800         case ConversionSpecifier::ZArg:
    801           return Target.getTriple().isOSMSVCRT();
    802         default:
    803           return false;
    804       }
    805   }
    806   llvm_unreachable("Invalid LengthModifier Kind!");
    807 }
    808 
    809 bool FormatSpecifier::hasStandardLengthModifier() const {
    810   switch (LM.getKind()) {
    811     case LengthModifier::None:
    812     case LengthModifier::AsChar:
    813     case LengthModifier::AsShort:
    814     case LengthModifier::AsLong:
    815     case LengthModifier::AsLongLong:
    816     case LengthModifier::AsIntMax:
    817     case LengthModifier::AsSizeT:
    818     case LengthModifier::AsPtrDiff:
    819     case LengthModifier::AsLongDouble:
    820       return true;
    821     case LengthModifier::AsAllocate:
    822     case LengthModifier::AsMAllocate:
    823     case LengthModifier::AsQuad:
    824     case LengthModifier::AsInt32:
    825     case LengthModifier::AsInt3264:
    826     case LengthModifier::AsInt64:
    827     case LengthModifier::AsWide:
    828       return false;
    829   }
    830   llvm_unreachable("Invalid LengthModifier Kind!");
    831 }
    832 
    833 bool FormatSpecifier::hasStandardConversionSpecifier(
    834     const LangOptions &LangOpt) const {
    835   switch (CS.getKind()) {
    836     case ConversionSpecifier::cArg:
    837     case ConversionSpecifier::dArg:
    838     case ConversionSpecifier::iArg:
    839     case ConversionSpecifier::oArg:
    840     case ConversionSpecifier::uArg:
    841     case ConversionSpecifier::xArg:
    842     case ConversionSpecifier::XArg:
    843     case ConversionSpecifier::fArg:
    844     case ConversionSpecifier::FArg:
    845     case ConversionSpecifier::eArg:
    846     case ConversionSpecifier::EArg:
    847     case ConversionSpecifier::gArg:
    848     case ConversionSpecifier::GArg:
    849     case ConversionSpecifier::aArg:
    850     case ConversionSpecifier::AArg:
    851     case ConversionSpecifier::sArg:
    852     case ConversionSpecifier::pArg:
    853     case ConversionSpecifier::nArg:
    854     case ConversionSpecifier::ObjCObjArg:
    855     case ConversionSpecifier::ScanListArg:
    856     case ConversionSpecifier::PercentArg:
    857       return true;
    858     case ConversionSpecifier::CArg:
    859     case ConversionSpecifier::SArg:
    860       return LangOpt.ObjC1 || LangOpt.ObjC2;
    861     case ConversionSpecifier::InvalidSpecifier:
    862     case ConversionSpecifier::FreeBSDbArg:
    863     case ConversionSpecifier::FreeBSDDArg:
    864     case ConversionSpecifier::FreeBSDrArg:
    865     case ConversionSpecifier::FreeBSDyArg:
    866     case ConversionSpecifier::PrintErrno:
    867     case ConversionSpecifier::DArg:
    868     case ConversionSpecifier::OArg:
    869     case ConversionSpecifier::UArg:
    870     case ConversionSpecifier::ZArg:
    871       return false;
    872   }
    873   llvm_unreachable("Invalid ConversionSpecifier Kind!");
    874 }
    875 
    876 bool FormatSpecifier::hasStandardLengthConversionCombination() const {
    877   if (LM.getKind() == LengthModifier::AsLongDouble) {
    878     switch(CS.getKind()) {
    879         case ConversionSpecifier::dArg:
    880         case ConversionSpecifier::iArg:
    881         case ConversionSpecifier::oArg:
    882         case ConversionSpecifier::uArg:
    883         case ConversionSpecifier::xArg:
    884         case ConversionSpecifier::XArg:
    885           return false;
    886         default:
    887           return true;
    888     }
    889   }
    890   return true;
    891 }
    892 
    893 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const {
    894   if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
    895     if (LM.getKind() == LengthModifier::AsLongDouble ||
    896         LM.getKind() == LengthModifier::AsQuad) {
    897       LengthModifier FixedLM(LM);
    898       FixedLM.setKind(LengthModifier::AsLongLong);
    899       return FixedLM;
    900     }
    901   }
    902 
    903   return None;
    904 }
    905 
    906 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
    907                                                 LengthModifier &LM) {
    908   assert(isa<TypedefType>(QT) && "Expected a TypedefType");
    909   const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
    910 
    911   for (;;) {
    912     const IdentifierInfo *Identifier = Typedef->getIdentifier();
    913     if (Identifier->getName() == "size_t") {
    914       LM.setKind(LengthModifier::AsSizeT);
    915       return true;
    916     } else if (Identifier->getName() == "ssize_t") {
    917       // Not C99, but common in Unix.
    918       LM.setKind(LengthModifier::AsSizeT);
    919       return true;
    920     } else if (Identifier->getName() == "intmax_t") {
    921       LM.setKind(LengthModifier::AsIntMax);
    922       return true;
    923     } else if (Identifier->getName() == "uintmax_t") {
    924       LM.setKind(LengthModifier::AsIntMax);
    925       return true;
    926     } else if (Identifier->getName() == "ptrdiff_t") {
    927       LM.setKind(LengthModifier::AsPtrDiff);
    928       return true;
    929     }
    930 
    931     QualType T = Typedef->getUnderlyingType();
    932     if (!isa<TypedefType>(T))
    933       break;
    934 
    935     Typedef = cast<TypedefType>(T)->getDecl();
    936   }
    937   return false;
    938 }
    939