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