clang  3.9.0
PrintfFormatString.cpp
Go to the documentation of this file.
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 
16 #include "FormatStringParsing.h"
17 #include "clang/Basic/TargetInfo.h"
18 
25 
26 using namespace clang;
27 
30 
31 //===----------------------------------------------------------------------===//
32 // Methods for parsing format strings.
33 //===----------------------------------------------------------------------===//
34 
36 
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,
45  if (Amt.isInvalid())
46  return true;
47  FS.setPrecision(Amt);
48  }
49  return false;
50 }
51 
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 
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++;
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)
268  break;
269  case 'y':
270  if (isFreeBSDKPrintf)
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())
279  break;
280  case 'O':
281  if (Target.getTriple().isOSDarwin())
283  break;
284  case 'U':
285  if (Target.getTriple().isOSDarwin())
287  break;
288  // MS specific.
289  case 'Z':
290  if (Target.getTriple().isOSMSVCRT())
292  }
293 
294  // Check to see if we used the Objective-C modifier flags with
295  // a conversion specifier other than '@'.
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.
312  argIndex++;
313 
315  unsigned Len = I - Start;
316  if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
317  CS.setEndScanList(Start + Len);
318  FS.setConversionSpecifier(CS);
319  }
320  // Assume the conversion takes one argument.
321  return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
322  }
323  return PrintfSpecifierResult(Start, FS);
324 }
325 
327  const char *I,
328  const char *E,
329  const LangOptions &LO,
330  const TargetInfo &Target,
331  bool isFreeBSDKPrintf) {
332 
333  unsigned argIndex = 0;
334 
335  // Keep looking for a format specifier until we have exhausted the string.
336  while (I != E) {
337  const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
338  LO, Target, true,
339  isFreeBSDKPrintf);
340  // Did a fail-stop error of any kind occur when parsing the specifier?
341  // If so, don't do any more processing.
342  if (FSR.shouldStop())
343  return true;
344  // Did we exhaust the string or encounter an error that
345  // we can recover from?
346  if (!FSR.hasValue())
347  continue;
348  // We have a format specifier. Pass it to the callback.
349  if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
350  I - FSR.getStart()))
351  return true;
352  }
353  assert(I == E && "Format string not exhausted");
354  return false;
355 }
356 
358  const char *E,
359  const LangOptions &LO,
360  const TargetInfo &Target) {
361 
362  unsigned argIndex = 0;
363 
364  // Keep looking for a %s format specifier until we have exhausted the string.
366  while (I != E) {
367  const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
368  LO, Target, false,
369  false);
370  // Did a fail-stop error of any kind occur when parsing the specifier?
371  // If so, don't do any more processing.
372  if (FSR.shouldStop())
373  return false;
374  // Did we exhaust the string or encounter an error that
375  // we can recover from?
376  if (!FSR.hasValue())
377  continue;
378  const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
379  // Return true if this a %s format specifier.
380  if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
381  return true;
382  }
383  return false;
384 }
385 
386 //===----------------------------------------------------------------------===//
387 // Methods on PrintfSpecifier.
388 //===----------------------------------------------------------------------===//
389 
390 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
391  bool IsObjCLiteral) const {
392  const PrintfConversionSpecifier &CS = getConversionSpecifier();
393 
394  if (!CS.consumesDataArgument())
395  return ArgType::Invalid();
396 
398  switch (LM.getKind()) {
400  return Ctx.IntTy;
403  return ArgType(ArgType::WIntTy, "wint_t");
405  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
406  return Ctx.IntTy;
407  default:
408  return ArgType::Invalid();
409  }
410 
411  if (CS.isIntArg())
412  switch (LM.getKind()) {
414  // GNU extension.
415  return Ctx.LongLongTy;
417  return Ctx.IntTy;
419  return ArgType(Ctx.IntTy, "__int32");
421  case LengthModifier::AsShort: return Ctx.ShortTy;
422  case LengthModifier::AsLong: return Ctx.LongTy;
425  return Ctx.LongLongTy;
427  return ArgType(Ctx.LongLongTy, "__int64");
429  return ArgType(Ctx.getIntMaxType(), "intmax_t");
431  // FIXME: How to get the corresponding signed version of size_t?
432  return ArgType();
434  return Ctx.getTargetInfo().getTriple().isArch64Bit()
435  ? ArgType(Ctx.LongLongTy, "__int64")
436  : ArgType(Ctx.IntTy, "__int32");
438  return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
442  return ArgType::Invalid();
443  }
444 
445  if (CS.isUIntArg())
446  switch (LM.getKind()) {
448  // GNU extension.
449  return Ctx.UnsignedLongLongTy;
451  return Ctx.UnsignedIntTy;
453  return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
454  case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
455  case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
456  case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
459  return Ctx.UnsignedLongLongTy;
461  return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
463  return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
465  return ArgType(Ctx.getSizeType(), "size_t");
467  return Ctx.getTargetInfo().getTriple().isArch64Bit()
468  ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
469  : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
471  // FIXME: How to get the corresponding unsigned
472  // version of ptrdiff_t?
473  return ArgType();
477  return ArgType::Invalid();
478  }
479 
480  if (CS.isDoubleArg()) {
481  if (LM.getKind() == LengthModifier::AsLongDouble)
482  return Ctx.LongDoubleTy;
483  return Ctx.DoubleTy;
484  }
485 
486  if (CS.getKind() == ConversionSpecifier::nArg) {
487  switch (LM.getKind()) {
489  return ArgType::PtrTo(Ctx.IntTy);
491  return ArgType::PtrTo(Ctx.SignedCharTy);
493  return ArgType::PtrTo(Ctx.ShortTy);
495  return ArgType::PtrTo(Ctx.LongTy);
498  return ArgType::PtrTo(Ctx.LongLongTy);
500  return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
502  return ArgType(); // FIXME: ssize_t
504  return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
506  return ArgType(); // FIXME: Is this a known extension?
513  return ArgType::Invalid();
514  }
515  }
516 
517  switch (CS.getKind()) {
519  if (LM.getKind() == LengthModifier::AsWideChar) {
520  if (IsObjCLiteral)
521  return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
522  "const unichar *");
523  return ArgType(ArgType::WCStrTy, "wchar_t *");
524  }
525  if (LM.getKind() == LengthModifier::AsWide)
526  return ArgType(ArgType::WCStrTy, "wchar_t *");
527  return ArgType::CStrTy;
529  if (IsObjCLiteral)
530  return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
531  "const unichar *");
532  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
533  LM.getKind() == LengthModifier::AsShort)
534  return ArgType::CStrTy;
535  return ArgType(ArgType::WCStrTy, "wchar_t *");
537  if (IsObjCLiteral)
538  return ArgType(Ctx.UnsignedShortTy, "unichar");
539  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
540  LM.getKind() == LengthModifier::AsShort)
541  return Ctx.IntTy;
542  return ArgType(Ctx.WideCharTy, "wchar_t");
544  return ArgType::CPointerTy;
546  return ArgType::ObjCPointerTy;
547  default:
548  break;
549  }
550 
551  // FIXME: Handle other cases.
552  return ArgType();
553 }
554 
555 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
556  ASTContext &Ctx, bool IsObjCLiteral) {
557  // %n is different from other conversion specifiers; don't try to fix it.
558  if (CS.getKind() == ConversionSpecifier::nArg)
559  return false;
560 
561  // Handle Objective-C objects first. Note that while the '%@' specifier will
562  // not warn for structure pointer or void pointer arguments (because that's
563  // how CoreFoundation objects are implemented), we only show a fixit for '%@'
564  // if we know it's an object (block, id, class, or __attribute__((NSObject))).
565  if (QT->isObjCRetainableType()) {
566  if (!IsObjCLiteral)
567  return false;
568 
570 
571  // Disable irrelevant flags
572  HasThousandsGrouping = false;
573  HasPlusPrefix = false;
574  HasSpacePrefix = false;
575  HasAlternativeForm = false;
576  HasLeadingZeroes = false;
577  Precision.setHowSpecified(OptionalAmount::NotSpecified);
578  LM.setKind(LengthModifier::None);
579 
580  return true;
581  }
582 
583  // Handle strings next (char *, wchar_t *)
584  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
585  CS.setKind(ConversionSpecifier::sArg);
586 
587  // Disable irrelevant flags
588  HasAlternativeForm = 0;
589  HasLeadingZeroes = 0;
590 
591  // Set the long length modifier for wide characters
592  if (QT->getPointeeType()->isWideCharType())
593  LM.setKind(LengthModifier::AsWideChar);
594  else
595  LM.setKind(LengthModifier::None);
596 
597  return true;
598  }
599 
600  // If it's an enum, get its underlying type.
601  if (const EnumType *ETy = QT->getAs<EnumType>())
602  QT = ETy->getDecl()->getIntegerType();
603 
604  // We can only work with builtin types.
605  const BuiltinType *BT = QT->getAs<BuiltinType>();
606  if (!BT)
607  return false;
608 
609  // Set length modifier
610  switch (BT->getKind()) {
611  case BuiltinType::Bool:
612  case BuiltinType::WChar_U:
613  case BuiltinType::WChar_S:
614  case BuiltinType::Char16:
615  case BuiltinType::Char32:
616  case BuiltinType::UInt128:
617  case BuiltinType::Int128:
618  case BuiltinType::Half:
619  case BuiltinType::Float128:
620  // Various types which are non-trivial to correct.
621  return false;
622 
623 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
624  case BuiltinType::Id:
625 #include "clang/Basic/OpenCLImageTypes.def"
626 #define SIGNED_TYPE(Id, SingletonId)
627 #define UNSIGNED_TYPE(Id, SingletonId)
628 #define FLOATING_TYPE(Id, SingletonId)
629 #define BUILTIN_TYPE(Id, SingletonId) \
630  case BuiltinType::Id:
631 #include "clang/AST/BuiltinTypes.def"
632  // Misc other stuff which doesn't make sense here.
633  return false;
634 
635  case BuiltinType::UInt:
636  case BuiltinType::Int:
637  case BuiltinType::Float:
638  case BuiltinType::Double:
639  LM.setKind(LengthModifier::None);
640  break;
641 
642  case BuiltinType::Char_U:
643  case BuiltinType::UChar:
644  case BuiltinType::Char_S:
645  case BuiltinType::SChar:
646  LM.setKind(LengthModifier::AsChar);
647  break;
648 
649  case BuiltinType::Short:
650  case BuiltinType::UShort:
651  LM.setKind(LengthModifier::AsShort);
652  break;
653 
654  case BuiltinType::Long:
655  case BuiltinType::ULong:
656  LM.setKind(LengthModifier::AsLong);
657  break;
658 
659  case BuiltinType::LongLong:
660  case BuiltinType::ULongLong:
661  LM.setKind(LengthModifier::AsLongLong);
662  break;
663 
664  case BuiltinType::LongDouble:
665  LM.setKind(LengthModifier::AsLongDouble);
666  break;
667  }
668 
669  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
670  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
671  namedTypeToLengthModifier(QT, LM);
672 
673  // If fixing the length modifier was enough, we might be done.
674  if (hasValidLengthModifier(Ctx.getTargetInfo())) {
675  // If we're going to offer a fix anyway, make sure the sign matches.
676  switch (CS.getKind()) {
679  if (QT->isSignedIntegerType())
681  break;
685  if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
687  break;
688  default:
689  // Other specifiers do not have signed/unsigned variants.
690  break;
691  }
692 
693  const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
694  if (ATR.isValid() && ATR.matchesType(Ctx, QT))
695  return true;
696  }
697 
698  // Set conversion specifier and disable any flags which do not apply to it.
699  // Let typedefs to char fall through to int, as %c is silly for uint8_t.
700  if (!isa<TypedefType>(QT) && QT->isCharType()) {
701  CS.setKind(ConversionSpecifier::cArg);
702  LM.setKind(LengthModifier::None);
703  Precision.setHowSpecified(OptionalAmount::NotSpecified);
704  HasAlternativeForm = 0;
705  HasLeadingZeroes = 0;
706  HasPlusPrefix = 0;
707  }
708  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
709  else if (QT->isRealFloatingType()) {
710  CS.setKind(ConversionSpecifier::fArg);
711  }
712  else if (QT->isSignedIntegerType()) {
713  CS.setKind(ConversionSpecifier::dArg);
714  HasAlternativeForm = 0;
715  }
716  else if (QT->isUnsignedIntegerType()) {
717  CS.setKind(ConversionSpecifier::uArg);
718  HasAlternativeForm = 0;
719  HasPlusPrefix = 0;
720  } else {
721  llvm_unreachable("Unexpected type");
722  }
723 
724  return true;
725 }
726 
727 void PrintfSpecifier::toString(raw_ostream &os) const {
728  // Whilst some features have no defined order, we are using the order
729  // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
730  os << "%";
731 
732  // Positional args
733  if (usesPositionalArg()) {
734  os << getPositionalArgIndex() << "$";
735  }
736 
737  // Conversion flags
738  if (IsLeftJustified) os << "-";
739  if (HasPlusPrefix) os << "+";
740  if (HasSpacePrefix) os << " ";
741  if (HasAlternativeForm) os << "#";
742  if (HasLeadingZeroes) os << "0";
743 
744  // Minimum field width
745  FieldWidth.toString(os);
746  // Precision
747  Precision.toString(os);
748  // Length modifier
749  os << LM.toString();
750  // Conversion specifier
751  os << CS.toString();
752 }
753 
754 bool PrintfSpecifier::hasValidPlusPrefix() const {
755  if (!HasPlusPrefix)
756  return true;
757 
758  // The plus prefix only makes sense for signed conversions
759  switch (CS.getKind()) {
773  return true;
774 
775  default:
776  return false;
777  }
778 }
779 
780 bool PrintfSpecifier::hasValidAlternativeForm() const {
781  if (!HasAlternativeForm)
782  return true;
783 
784  // Alternate form flag only valid with the oxXaAeEfFgG conversions
785  switch (CS.getKind()) {
800  return true;
801 
802  default:
803  return false;
804  }
805 }
806 
807 bool PrintfSpecifier::hasValidLeadingZeros() const {
808  if (!HasLeadingZeroes)
809  return true;
810 
811  // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
812  switch (CS.getKind()) {
832  return true;
833 
834  default:
835  return false;
836  }
837 }
838 
839 bool PrintfSpecifier::hasValidSpacePrefix() const {
840  if (!HasSpacePrefix)
841  return true;
842 
843  // The space prefix only makes sense for signed conversions
844  switch (CS.getKind()) {
858  return true;
859 
860  default:
861  return false;
862  }
863 }
864 
865 bool PrintfSpecifier::hasValidLeftJustified() const {
866  if (!IsLeftJustified)
867  return true;
868 
869  // The left justified flag is valid for all conversions except n
870  switch (CS.getKind()) {
872  return false;
873 
874  default:
875  return true;
876  }
877 }
878 
879 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
880  if (!HasThousandsGrouping)
881  return true;
882 
883  switch (CS.getKind()) {
893  return true;
894  default:
895  return false;
896  }
897 }
898 
899 bool PrintfSpecifier::hasValidPrecision() const {
900  if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
901  return true;
902 
903  // Precision is only valid with the diouxXaAeEfFgGs conversions
904  switch (CS.getKind()) {
925  return true;
926 
927  default:
928  return false;
929  }
930 }
931 bool PrintfSpecifier::hasValidFieldWidth() const {
932  if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
933  return true;
934 
935  // The field width is valid for all conversions except n
936  switch (CS.getKind()) {
938  return false;
939 
940  default:
941  return true;
942  }
943 }
Kind getKind() const
Definition: Type.h:2060
CanQualType LongLongTy
Definition: ASTContext.h:901
A (possibly-)qualified type.
Definition: Type.h:598
bool isCharType() const
Definition: Type.cpp:1656
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
Definition: Type.cpp:1686
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
virtual void HandleInvalidObjCModifierFlag(const char *startFlag, unsigned flagLen)
Definition: FormatString.h:625
static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS, const char *FlagBeg, const char *E, bool Warn)
static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E)
CanQualType LongTy
Definition: ASTContext.h:901
CanQualType WideCharTy
Definition: ASTContext.h:897
bool isObjCRetainableType() const
Definition: Type.cpp:3699
virtual void HandleEmptyObjCModifierFlag(const char *startFlags, unsigned flagsLen)
Definition: FormatString.h:622
QualType withConst() const
Retrieves a version of this type with const applied.
CanQualType getIntMaxType() const
Return the unique type for "intmax_t" (C99 7.18.1.5), defined in <stdint.h>.
void setPrecision(const OptionalAmount &Amt)
Definition: FormatString.h:483
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
virtual bool HandleInvalidPrintfConversionSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:633
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:588
Represents the length modifier in a format string in scanf/printf.
Definition: FormatString.h:65
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
Definition: Type.cpp:1746
CanQualType LongDoubleTy
Definition: ASTContext.h:904
detail::InMemoryDirectory::const_iterator I
CanQualType UnsignedCharTy
Definition: ASTContext.h:902
static ArgType PtrTo(const ArgType &A)
Create an ArgType which corresponds to the type pointer to A.
Definition: FormatString.h:259
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex)
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:415
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:1799
Exposes information about the current target.
CanQualType getUIntMaxType() const
Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in <stdint.h>.
CanQualType ShortTy
Definition: ASTContext.h:901
virtual void HandleNullChar(const char *nullCharacter)
Definition: FormatString.h:610
const PrintfConversionSpecifier & getConversionSpecifier() const
Definition: FormatString.h:479
CanQualType SignedCharTy
Definition: ASTContext.h:901
bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart, const char *flagsEnd, const char *conversionPosition)
Definition: FormatString.h:628
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:3733
bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:640
CanQualType UnsignedShortTy
Definition: ASTContext.h:902
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:903
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
detail::InMemoryDirectory::const_iterator E
bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len)
Returns true if the invalid specifier in SpecifierBegin is a UTF-8 string; check that it won't go fur...
bool isWideCharType() const
Definition: Type.cpp:1665
std::string toString(const til::SExpr *E)
void setHasObjCTechnicalTerm(const char *position)
Definition: FormatString.h:472
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:5818
CanQualType UnsignedLongTy
Definition: ASTContext.h:902
bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO, bool IsScanf=false)
Returns true if a LengthModifier was parsed and installed in the FormatSpecifier& argument...
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:619
This class is used for builtin types like 'int'.
Definition: Type.h:2039
Defines the clang::TargetInfo interface.
CanQualType IntTy
Definition: ASTContext.h:901
bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)
clang::analyze_format_string::SpecifierResult< PrintfSpecifier > PrintfSpecifierResult
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
Definition: Type.cpp:1706
CanQualType DoubleTy
Definition: ASTContext.h:904
static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, unsigned &argIndex, const LangOptions &LO, const TargetInfo &Target, bool Warn, bool isFreeBSDKPrintf)
CanQualType UnsignedIntTy
Definition: ASTContext.h:902
OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start, const char *&Beg, const char *E, PositionContext p)
bool isPointerType() const
Definition: Type.h:5482