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