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