clang  9.0.0svn
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 
15 #include "clang/AST/FormatString.h"
16 #include "clang/AST/OSLog.h"
17 #include "FormatStringParsing.h"
18 #include "clang/Basic/TargetInfo.h"
19 
26 
27 using namespace clang;
28 
31 
32 //===----------------------------------------------------------------------===//
33 // Methods for parsing format strings.
34 //===----------------------------------------------------------------------===//
35 
37 
39  const char *Start, const char *&Beg, const char *E,
40  unsigned *argIndex) {
41  if (argIndex) {
42  FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
43  } else {
44  const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
46  if (Amt.isInvalid())
47  return true;
48  FS.setPrecision(Amt);
49  }
50  return false;
51 }
52 
54  const char *FlagBeg, const char *E, bool Warn) {
55  StringRef Flag(FlagBeg, E - FlagBeg);
56  // Currently there is only one flag.
57  if (Flag == "tt") {
58  FS.setHasObjCTechnicalTerm(FlagBeg);
59  return false;
60  }
61  // Handle either the case of no flag or an invalid flag.
62  if (Warn) {
63  if (Flag == "")
64  H.HandleEmptyObjCModifierFlag(FlagBeg, E - FlagBeg);
65  else
66  H.HandleInvalidObjCModifierFlag(FlagBeg, E - FlagBeg);
67  }
68  return true;
69 }
70 
72  const char *&Beg,
73  const char *E,
74  unsigned &argIndex,
75  const LangOptions &LO,
76  const TargetInfo &Target,
77  bool Warn,
78  bool isFreeBSDKPrintf) {
79 
80  using namespace clang::analyze_format_string;
81  using namespace clang::analyze_printf;
82 
83  const char *I = Beg;
84  const char *Start = nullptr;
85  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
86 
87  // Look for a '%' character that indicates the start of a format specifier.
88  for ( ; I != E ; ++I) {
89  char c = *I;
90  if (c == '\0') {
91  // Detect spurious null characters, which are likely errors.
92  H.HandleNullChar(I);
93  return true;
94  }
95  if (c == '%') {
96  Start = I++; // Record the start of the format specifier.
97  break;
98  }
99  }
100 
101  // No format specifier found?
102  if (!Start)
103  return false;
104 
105  if (I == E) {
106  // No more characters left?
107  if (Warn)
108  H.HandleIncompleteSpecifier(Start, E - Start);
109  return true;
110  }
111 
112  PrintfSpecifier FS;
113  if (ParseArgPosition(H, FS, Start, I, E))
114  return true;
115 
116  if (I == E) {
117  // No more characters left?
118  if (Warn)
119  H.HandleIncompleteSpecifier(Start, E - Start);
120  return true;
121  }
122 
123  if (*I == '{') {
124  ++I;
125  unsigned char PrivacyFlags = 0;
126  StringRef MatchedStr;
127 
128  do {
129  StringRef Str(I, E - I);
130  std::string Match = "^[[:space:]]*"
131  "(private|public|sensitive|mask\\.[^[:space:],}]*)"
132  "[[:space:]]*(,|})";
133  llvm::Regex R(Match);
135 
136  if (R.match(Str, &Matches)) {
137  MatchedStr = Matches[1];
138  I += Matches[0].size();
139 
140  // Set the privacy flag if the privacy annotation in the
141  // comma-delimited segment is at least as strict as the privacy
142  // annotations in previous comma-delimited segments.
143  if (MatchedStr.startswith("mask")) {
144  StringRef MaskType = MatchedStr.substr(sizeof("mask.") - 1);
145  unsigned Size = MaskType.size();
146  if (Warn && (Size == 0 || Size > 8))
147  H.handleInvalidMaskType(MaskType);
148  FS.setMaskType(MaskType);
149  } else if (MatchedStr.equals("sensitive"))
151  else if (PrivacyFlags !=
153  MatchedStr.equals("private"))
155  else if (PrivacyFlags == 0 && MatchedStr.equals("public"))
157  } else {
158  size_t CommaOrBracePos =
159  Str.find_if([](char c) { return c == ',' || c == '}'; });
160 
161  if (CommaOrBracePos == StringRef::npos) {
162  // Neither a comma nor the closing brace was found.
163  if (Warn)
164  H.HandleIncompleteSpecifier(Start, E - Start);
165  return true;
166  }
167 
168  I += CommaOrBracePos + 1;
169  }
170  // Continue until the closing brace is found.
171  } while (*(I - 1) == ',');
172 
173  // Set the privacy flag.
174  switch (PrivacyFlags) {
175  case 0:
176  break;
178  FS.setIsPrivate(MatchedStr.data());
179  break;
181  FS.setIsPublic(MatchedStr.data());
182  break;
184  FS.setIsSensitive(MatchedStr.data());
185  break;
186  default:
187  llvm_unreachable("Unexpected privacy flag value");
188  }
189  }
190 
191  // Look for flags (if any).
192  bool hasMore = true;
193  for ( ; I != E; ++I) {
194  switch (*I) {
195  default: hasMore = false; break;
196  case '\'':
197  // FIXME: POSIX specific. Always accept?
199  break;
200  case '-': FS.setIsLeftJustified(I); break;
201  case '+': FS.setHasPlusPrefix(I); break;
202  case ' ': FS.setHasSpacePrefix(I); break;
203  case '#': FS.setHasAlternativeForm(I); break;
204  case '0': FS.setHasLeadingZeros(I); break;
205  }
206  if (!hasMore)
207  break;
208  }
209 
210  if (I == E) {
211  // No more characters left?
212  if (Warn)
213  H.HandleIncompleteSpecifier(Start, E - Start);
214  return true;
215  }
216 
217  // Look for the field width (if any).
218  if (ParseFieldWidth(H, FS, Start, I, E,
219  FS.usesPositionalArg() ? nullptr : &argIndex))
220  return true;
221 
222  if (I == E) {
223  // No more characters left?
224  if (Warn)
225  H.HandleIncompleteSpecifier(Start, E - Start);
226  return true;
227  }
228 
229  // Look for the precision (if any).
230  if (*I == '.') {
231  ++I;
232  if (I == E) {
233  if (Warn)
234  H.HandleIncompleteSpecifier(Start, E - Start);
235  return true;
236  }
237 
238  if (ParsePrecision(H, FS, Start, I, E,
239  FS.usesPositionalArg() ? nullptr : &argIndex))
240  return true;
241 
242  if (I == E) {
243  // No more characters left?
244  if (Warn)
245  H.HandleIncompleteSpecifier(Start, E - Start);
246  return true;
247  }
248  }
249 
250  if (ParseVectorModifier(H, FS, I, E, LO))
251  return true;
252 
253  // Look for the length modifier.
254  if (ParseLengthModifier(FS, I, E, LO) && I == E) {
255  // No more characters left?
256  if (Warn)
257  H.HandleIncompleteSpecifier(Start, E - Start);
258  return true;
259  }
260 
261  // Look for the Objective-C modifier flags, if any.
262  // We parse these here, even if they don't apply to
263  // the conversion specifier, and then emit an error
264  // later if the conversion specifier isn't '@'. This
265  // enables better recovery, and we don't know if
266  // these flags are applicable until later.
267  const char *ObjCModifierFlagsStart = nullptr,
268  *ObjCModifierFlagsEnd = nullptr;
269  if (*I == '[') {
270  ObjCModifierFlagsStart = I;
271  ++I;
272  auto flagStart = I;
273  for (;; ++I) {
274  ObjCModifierFlagsEnd = I;
275  if (I == E) {
276  if (Warn)
277  H.HandleIncompleteSpecifier(Start, E - Start);
278  return true;
279  }
280  // Did we find the closing ']'?
281  if (*I == ']') {
282  if (ParseObjCFlags(H, FS, flagStart, I, Warn))
283  return true;
284  ++I;
285  break;
286  }
287  // There are no separators defined yet for multiple
288  // Objective-C modifier flags. When those are
289  // defined, this is the place to check.
290  }
291  }
292 
293  if (*I == '\0') {
294  // Detect spurious null characters, which are likely errors.
295  H.HandleNullChar(I);
296  return true;
297  }
298 
299  // Finally, look for the conversion specifier.
300  const char *conversionPosition = I++;
302  switch (*conversionPosition) {
303  default:
304  break;
305  // C99: 7.19.6.1 (section 8).
306  case '%': k = ConversionSpecifier::PercentArg; break;
307  case 'A': k = ConversionSpecifier::AArg; break;
308  case 'E': k = ConversionSpecifier::EArg; break;
309  case 'F': k = ConversionSpecifier::FArg; break;
310  case 'G': k = ConversionSpecifier::GArg; break;
311  case 'X': k = ConversionSpecifier::XArg; break;
312  case 'a': k = ConversionSpecifier::aArg; break;
313  case 'c': k = ConversionSpecifier::cArg; break;
314  case 'd': k = ConversionSpecifier::dArg; break;
315  case 'e': k = ConversionSpecifier::eArg; break;
316  case 'f': k = ConversionSpecifier::fArg; break;
317  case 'g': k = ConversionSpecifier::gArg; break;
318  case 'i': k = ConversionSpecifier::iArg; break;
319  case 'n': k = ConversionSpecifier::nArg; break;
320  case 'o': k = ConversionSpecifier::oArg; break;
321  case 'p': k = ConversionSpecifier::pArg; break;
322  case 's': k = ConversionSpecifier::sArg; break;
323  case 'u': k = ConversionSpecifier::uArg; break;
324  case 'x': k = ConversionSpecifier::xArg; break;
325  // POSIX specific.
326  case 'C': k = ConversionSpecifier::CArg; break;
327  case 'S': k = ConversionSpecifier::SArg; break;
328  // Apple extension for os_log
329  case 'P':
331  break;
332  // Objective-C.
333  case '@': k = ConversionSpecifier::ObjCObjArg; break;
334  // Glibc specific.
335  case 'm': k = ConversionSpecifier::PrintErrno; break;
336  // FreeBSD kernel specific.
337  case 'b':
338  if (isFreeBSDKPrintf)
339  k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
340  break;
341  case 'r':
342  if (isFreeBSDKPrintf)
344  break;
345  case 'y':
346  if (isFreeBSDKPrintf)
348  break;
349  // Apple-specific.
350  case 'D':
351  if (isFreeBSDKPrintf)
352  k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
353  else if (Target.getTriple().isOSDarwin())
355  break;
356  case 'O':
357  if (Target.getTriple().isOSDarwin())
359  break;
360  case 'U':
361  if (Target.getTriple().isOSDarwin())
363  break;
364  // MS specific.
365  case 'Z':
366  if (Target.getTriple().isOSMSVCRT())
368  break;
369  }
370 
371  // Check to see if we used the Objective-C modifier flags with
372  // a conversion specifier other than '@'.
375  ObjCModifierFlagsStart) {
376  H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
377  ObjCModifierFlagsEnd + 1,
378  conversionPosition);
379  return true;
380  }
381 
382  PrintfConversionSpecifier CS(conversionPosition, k);
383  FS.setConversionSpecifier(CS);
384  if (CS.consumesDataArgument() && !FS.usesPositionalArg())
385  FS.setArgIndex(argIndex++);
386  // FreeBSD kernel specific.
389  argIndex++;
390 
392  unsigned Len = I - Start;
393  if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
394  CS.setEndScanList(Start + Len);
395  FS.setConversionSpecifier(CS);
396  }
397  // Assume the conversion takes one argument.
398  return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
399  }
400  return PrintfSpecifierResult(Start, FS);
401 }
402 
404  const char *I,
405  const char *E,
406  const LangOptions &LO,
407  const TargetInfo &Target,
408  bool isFreeBSDKPrintf) {
409 
410  unsigned argIndex = 0;
411 
412  // Keep looking for a format specifier until we have exhausted the string.
413  while (I != E) {
414  const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
415  LO, Target, true,
416  isFreeBSDKPrintf);
417  // Did a fail-stop error of any kind occur when parsing the specifier?
418  // If so, don't do any more processing.
419  if (FSR.shouldStop())
420  return true;
421  // Did we exhaust the string or encounter an error that
422  // we can recover from?
423  if (!FSR.hasValue())
424  continue;
425  // We have a format specifier. Pass it to the callback.
426  if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
427  I - FSR.getStart()))
428  return true;
429  }
430  assert(I == E && "Format string not exhausted");
431  return false;
432 }
433 
435  const char *E,
436  const LangOptions &LO,
437  const TargetInfo &Target) {
438 
439  unsigned argIndex = 0;
440 
441  // Keep looking for a %s format specifier until we have exhausted the string.
443  while (I != E) {
444  const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
445  LO, Target, false,
446  false);
447  // Did a fail-stop error of any kind occur when parsing the specifier?
448  // If so, don't do any more processing.
449  if (FSR.shouldStop())
450  return false;
451  // Did we exhaust the string or encounter an error that
452  // we can recover from?
453  if (!FSR.hasValue())
454  continue;
455  const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
456  // Return true if this a %s format specifier.
457  if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
458  return true;
459  }
460  return false;
461 }
462 
463 //===----------------------------------------------------------------------===//
464 // Methods on PrintfSpecifier.
465 //===----------------------------------------------------------------------===//
466 
467 ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
468  bool IsObjCLiteral) const {
469  if (CS.getKind() == ConversionSpecifier::cArg)
470  switch (LM.getKind()) {
472  return Ctx.IntTy;
475  return ArgType(ArgType::WIntTy, "wint_t");
477  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
478  return Ctx.IntTy;
479  LLVM_FALLTHROUGH;
480  default:
481  return ArgType::Invalid();
482  }
483 
484  if (CS.isIntArg())
485  switch (LM.getKind()) {
487  // GNU extension.
488  return Ctx.LongLongTy;
490  return Ctx.IntTy;
492  return ArgType(Ctx.IntTy, "__int32");
494  case LengthModifier::AsShort: return Ctx.ShortTy;
495  case LengthModifier::AsLong: return Ctx.LongTy;
498  return Ctx.LongLongTy;
500  return ArgType(Ctx.LongLongTy, "__int64");
502  return ArgType(Ctx.getIntMaxType(), "intmax_t");
504  return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
506  return Ctx.getTargetInfo().getTriple().isArch64Bit()
507  ? ArgType(Ctx.LongLongTy, "__int64")
508  : ArgType(Ctx.IntTy, "__int32");
510  return ArgType::makePtrdiffT(
511  ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
515  return ArgType::Invalid();
516  }
517 
518  if (CS.isUIntArg())
519  switch (LM.getKind()) {
521  // GNU extension.
522  return Ctx.UnsignedLongLongTy;
524  return Ctx.UnsignedIntTy;
526  return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
527  case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
528  case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
529  case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
532  return Ctx.UnsignedLongLongTy;
534  return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
536  return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
538  return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t"));
540  return Ctx.getTargetInfo().getTriple().isArch64Bit()
541  ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
542  : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
544  return ArgType::makePtrdiffT(
545  ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
549  return ArgType::Invalid();
550  }
551 
552  if (CS.isDoubleArg()) {
553  if (LM.getKind() == LengthModifier::AsLongDouble)
554  return Ctx.LongDoubleTy;
555  return Ctx.DoubleTy;
556  }
557 
558  if (CS.getKind() == ConversionSpecifier::nArg) {
559  switch (LM.getKind()) {
561  return ArgType::PtrTo(Ctx.IntTy);
563  return ArgType::PtrTo(Ctx.SignedCharTy);
565  return ArgType::PtrTo(Ctx.ShortTy);
567  return ArgType::PtrTo(Ctx.LongTy);
570  return ArgType::PtrTo(Ctx.LongLongTy);
572  return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
574  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
576  return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
578  return ArgType(); // FIXME: Is this a known extension?
585  return ArgType::Invalid();
586  }
587  }
588 
589  switch (CS.getKind()) {
591  if (LM.getKind() == LengthModifier::AsWideChar) {
592  if (IsObjCLiteral)
594  "const unichar *");
595  return ArgType(ArgType::WCStrTy, "wchar_t *");
596  }
597  if (LM.getKind() == LengthModifier::AsWide)
598  return ArgType(ArgType::WCStrTy, "wchar_t *");
599  return ArgType::CStrTy;
601  if (IsObjCLiteral)
603  "const unichar *");
604  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
605  LM.getKind() == LengthModifier::AsShort)
606  return ArgType::CStrTy;
607  return ArgType(ArgType::WCStrTy, "wchar_t *");
609  if (IsObjCLiteral)
610  return ArgType(Ctx.UnsignedShortTy, "unichar");
611  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
612  LM.getKind() == LengthModifier::AsShort)
613  return Ctx.IntTy;
614  return ArgType(Ctx.WideCharTy, "wchar_t");
617  return ArgType::CPointerTy;
619  return ArgType::ObjCPointerTy;
620  default:
621  break;
622  }
623 
624  // FIXME: Handle other cases.
625  return ArgType();
626 }
627 
628 
629 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
630  bool IsObjCLiteral) const {
631  const PrintfConversionSpecifier &CS = getConversionSpecifier();
632 
633  if (!CS.consumesDataArgument())
634  return ArgType::Invalid();
635 
636  ArgType ScalarTy = getScalarArgType(Ctx, IsObjCLiteral);
637  if (!ScalarTy.isValid() || VectorNumElts.isInvalid())
638  return ScalarTy;
639 
640  return ScalarTy.makeVectorType(Ctx, VectorNumElts.getConstantAmount());
641 }
642 
643 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
644  ASTContext &Ctx, bool IsObjCLiteral) {
645  // %n is different from other conversion specifiers; don't try to fix it.
646  if (CS.getKind() == ConversionSpecifier::nArg)
647  return false;
648 
649  // Handle Objective-C objects first. Note that while the '%@' specifier will
650  // not warn for structure pointer or void pointer arguments (because that's
651  // how CoreFoundation objects are implemented), we only show a fixit for '%@'
652  // if we know it's an object (block, id, class, or __attribute__((NSObject))).
653  if (QT->isObjCRetainableType()) {
654  if (!IsObjCLiteral)
655  return false;
656 
658 
659  // Disable irrelevant flags
660  HasThousandsGrouping = false;
661  HasPlusPrefix = false;
662  HasSpacePrefix = false;
663  HasAlternativeForm = false;
664  HasLeadingZeroes = false;
665  Precision.setHowSpecified(OptionalAmount::NotSpecified);
666  LM.setKind(LengthModifier::None);
667 
668  return true;
669  }
670 
671  // Handle strings next (char *, wchar_t *)
672  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
673  CS.setKind(ConversionSpecifier::sArg);
674 
675  // Disable irrelevant flags
676  HasAlternativeForm = 0;
677  HasLeadingZeroes = 0;
678 
679  // Set the long length modifier for wide characters
680  if (QT->getPointeeType()->isWideCharType())
681  LM.setKind(LengthModifier::AsWideChar);
682  else
683  LM.setKind(LengthModifier::None);
684 
685  return true;
686  }
687 
688  // If it's an enum, get its underlying type.
689  if (const EnumType *ETy = QT->getAs<EnumType>())
690  QT = ETy->getDecl()->getIntegerType();
691 
692  const BuiltinType *BT = QT->getAs<BuiltinType>();
693  if (!BT) {
694  const VectorType *VT = QT->getAs<VectorType>();
695  if (VT) {
696  QT = VT->getElementType();
697  BT = QT->getAs<BuiltinType>();
698  VectorNumElts = OptionalAmount(VT->getNumElements());
699  }
700  }
701 
702  // We can only work with builtin types.
703  if (!BT)
704  return false;
705 
706  // Set length modifier
707  switch (BT->getKind()) {
708  case BuiltinType::Bool:
709  case BuiltinType::WChar_U:
710  case BuiltinType::WChar_S:
711  case BuiltinType::Char8: // FIXME: Treat like 'char'?
712  case BuiltinType::Char16:
713  case BuiltinType::Char32:
714  case BuiltinType::UInt128:
715  case BuiltinType::Int128:
716  case BuiltinType::Half:
717  case BuiltinType::Float16:
718  case BuiltinType::Float128:
719  case BuiltinType::ShortAccum:
720  case BuiltinType::Accum:
721  case BuiltinType::LongAccum:
722  case BuiltinType::UShortAccum:
723  case BuiltinType::UAccum:
724  case BuiltinType::ULongAccum:
725  case BuiltinType::ShortFract:
726  case BuiltinType::Fract:
727  case BuiltinType::LongFract:
728  case BuiltinType::UShortFract:
729  case BuiltinType::UFract:
730  case BuiltinType::ULongFract:
731  case BuiltinType::SatShortAccum:
732  case BuiltinType::SatAccum:
733  case BuiltinType::SatLongAccum:
734  case BuiltinType::SatUShortAccum:
735  case BuiltinType::SatUAccum:
736  case BuiltinType::SatULongAccum:
737  case BuiltinType::SatShortFract:
738  case BuiltinType::SatFract:
739  case BuiltinType::SatLongFract:
740  case BuiltinType::SatUShortFract:
741  case BuiltinType::SatUFract:
742  case BuiltinType::SatULongFract:
743  // Various types which are non-trivial to correct.
744  return false;
745 
746 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
747  case BuiltinType::Id:
748 #include "clang/Basic/OpenCLImageTypes.def"
749 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
750  case BuiltinType::Id:
751 #include "clang/Basic/OpenCLExtensionTypes.def"
752 #define SIGNED_TYPE(Id, SingletonId)
753 #define UNSIGNED_TYPE(Id, SingletonId)
754 #define FLOATING_TYPE(Id, SingletonId)
755 #define BUILTIN_TYPE(Id, SingletonId) \
756  case BuiltinType::Id:
757 #include "clang/AST/BuiltinTypes.def"
758  // Misc other stuff which doesn't make sense here.
759  return false;
760 
761  case BuiltinType::UInt:
762  case BuiltinType::Int:
763  case BuiltinType::Float:
764  case BuiltinType::Double:
765  LM.setKind(LengthModifier::None);
766  break;
767 
768  case BuiltinType::Char_U:
769  case BuiltinType::UChar:
770  case BuiltinType::Char_S:
771  case BuiltinType::SChar:
772  LM.setKind(LengthModifier::AsChar);
773  break;
774 
775  case BuiltinType::Short:
776  case BuiltinType::UShort:
777  LM.setKind(LengthModifier::AsShort);
778  break;
779 
780  case BuiltinType::Long:
781  case BuiltinType::ULong:
782  LM.setKind(LengthModifier::AsLong);
783  break;
784 
785  case BuiltinType::LongLong:
786  case BuiltinType::ULongLong:
787  LM.setKind(LengthModifier::AsLongLong);
788  break;
789 
790  case BuiltinType::LongDouble:
791  LM.setKind(LengthModifier::AsLongDouble);
792  break;
793  }
794 
795  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
796  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
797  namedTypeToLengthModifier(QT, LM);
798 
799  // If fixing the length modifier was enough, we might be done.
800  if (hasValidLengthModifier(Ctx.getTargetInfo())) {
801  // If we're going to offer a fix anyway, make sure the sign matches.
802  switch (CS.getKind()) {
805  if (QT->isSignedIntegerType())
807  break;
811  if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
813  break;
814  default:
815  // Other specifiers do not have signed/unsigned variants.
816  break;
817  }
818 
819  const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
820  if (ATR.isValid() && ATR.matchesType(Ctx, QT))
821  return true;
822  }
823 
824  // Set conversion specifier and disable any flags which do not apply to it.
825  // Let typedefs to char fall through to int, as %c is silly for uint8_t.
826  if (!isa<TypedefType>(QT) && QT->isCharType()) {
827  CS.setKind(ConversionSpecifier::cArg);
828  LM.setKind(LengthModifier::None);
829  Precision.setHowSpecified(OptionalAmount::NotSpecified);
830  HasAlternativeForm = 0;
831  HasLeadingZeroes = 0;
832  HasPlusPrefix = 0;
833  }
834  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
835  else if (QT->isRealFloatingType()) {
836  CS.setKind(ConversionSpecifier::fArg);
837  }
838  else if (QT->isSignedIntegerType()) {
839  CS.setKind(ConversionSpecifier::dArg);
840  HasAlternativeForm = 0;
841  }
842  else if (QT->isUnsignedIntegerType()) {
843  CS.setKind(ConversionSpecifier::uArg);
844  HasAlternativeForm = 0;
845  HasPlusPrefix = 0;
846  } else {
847  llvm_unreachable("Unexpected type");
848  }
849 
850  return true;
851 }
852 
853 void PrintfSpecifier::toString(raw_ostream &os) const {
854  // Whilst some features have no defined order, we are using the order
855  // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
856  os << "%";
857 
858  // Positional args
859  if (usesPositionalArg()) {
860  os << getPositionalArgIndex() << "$";
861  }
862 
863  // Conversion flags
864  if (IsLeftJustified) os << "-";
865  if (HasPlusPrefix) os << "+";
866  if (HasSpacePrefix) os << " ";
867  if (HasAlternativeForm) os << "#";
868  if (HasLeadingZeroes) os << "0";
869 
870  // Minimum field width
871  FieldWidth.toString(os);
872  // Precision
873  Precision.toString(os);
874 
875  // Vector modifier
876  if (!VectorNumElts.isInvalid())
877  os << 'v' << VectorNumElts.getConstantAmount();
878 
879  // Length modifier
880  os << LM.toString();
881  // Conversion specifier
882  os << CS.toString();
883 }
884 
885 bool PrintfSpecifier::hasValidPlusPrefix() const {
886  if (!HasPlusPrefix)
887  return true;
888 
889  // The plus prefix only makes sense for signed conversions
890  switch (CS.getKind()) {
904  return true;
905 
906  default:
907  return false;
908  }
909 }
910 
911 bool PrintfSpecifier::hasValidAlternativeForm() const {
912  if (!HasAlternativeForm)
913  return true;
914 
915  // Alternate form flag only valid with the oxXaAeEfFgG conversions
916  switch (CS.getKind()) {
931  return true;
932 
933  default:
934  return false;
935  }
936 }
937 
938 bool PrintfSpecifier::hasValidLeadingZeros() const {
939  if (!HasLeadingZeroes)
940  return true;
941 
942  // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
943  switch (CS.getKind()) {
963  return true;
964 
965  default:
966  return false;
967  }
968 }
969 
970 bool PrintfSpecifier::hasValidSpacePrefix() const {
971  if (!HasSpacePrefix)
972  return true;
973 
974  // The space prefix only makes sense for signed conversions
975  switch (CS.getKind()) {
989  return true;
990 
991  default:
992  return false;
993  }
994 }
995 
996 bool PrintfSpecifier::hasValidLeftJustified() const {
997  if (!IsLeftJustified)
998  return true;
999 
1000  // The left justified flag is valid for all conversions except n
1001  switch (CS.getKind()) {
1003  return false;
1004 
1005  default:
1006  return true;
1007  }
1008 }
1009 
1010 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
1011  if (!HasThousandsGrouping)
1012  return true;
1013 
1014  switch (CS.getKind()) {
1024  return true;
1025  default:
1026  return false;
1027  }
1028 }
1029 
1030 bool PrintfSpecifier::hasValidPrecision() const {
1031  if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
1032  return true;
1033 
1034  // Precision is only valid with the diouxXaAeEfFgGsP conversions
1035  switch (CS.getKind()) {
1057  return true;
1058 
1059  default:
1060  return false;
1061  }
1062 }
1063 bool PrintfSpecifier::hasValidFieldWidth() const {
1064  if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
1065  return true;
1066 
1067  // The field width is valid for all conversions except n
1068  switch (CS.getKind()) {
1070  return false;
1071 
1072  default:
1073  return true;
1074  }
1075 }
QualType withConst() const
Retrieves a version of this type with const applied.
CanQualType LongLongTy
Definition: ASTContext.h:1025
static ArgType makePtrdiffT(const ArgType &A)
Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t type.
Definition: FormatString.h:296
A (possibly-)qualified type.
Definition: Type.h:638
void setIsPublic(const char *position)
Definition: FormatString.h:537
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
Kind getKind() const
Definition: Type.h:2421
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:505
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:949
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:1937
bool ParseVectorModifier(FormatStringHandler &H, FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO)
virtual void HandleInvalidObjCModifierFlag(const char *startFlag, unsigned flagLen)
Definition: FormatString.h:697
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:1025
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:690
void setHasLeadingZeros(const char *position)
Definition: FormatString.h:530
CanQualType WideCharTy
Definition: ASTContext.h:1020
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:1884
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6755
virtual void HandleEmptyObjCModifierFlag(const char *startFlags, unsigned flagsLen)
Definition: FormatString.h:694
bool isWideCharType() const
Definition: Type.cpp:1796
void setPrecision(const OptionalAmount &Amt)
Definition: FormatString.h:549
static ArgType makeSizeT(const ArgType &A)
Create an ArgType which corresponds to the size_t/ssize_t type.
Definition: FormatString.h:288
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:155
Pieces specific to fprintf format strings.
Definition: FormatString.h:460
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
bool isCharType() const
Definition: Type.cpp:1787
void setHasSpacePrefix(const char *position)
Definition: FormatString.h:524
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
void setConversionSpecifier(const PrintfConversionSpecifier &cs)
Definition: FormatString.h:512
virtual bool HandleInvalidPrintfConversionSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:705
MatchKind matchesType(ASTContext &C, QualType argTy) const
Represents the length modifier in a format string in scanf/printf.
Definition: FormatString.h:65
CanQualType LongDoubleTy
Definition: ASTContext.h:1028
void setIsLeftJustified(const char *position)
Definition: FormatString.h:518
virtual void handleInvalidMaskType(StringRef MaskType)
Handle mask types whose sizes are not between one and eight bytes.
Definition: FormatString.h:719
CanQualType UnsignedCharTy
Definition: ASTContext.h:1026
static ArgType PtrTo(const ArgType &A)
Create an ArgType which corresponds to the type pointer to A.
Definition: FormatString.h:280
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex)
ArgType makeVectorType(ASTContext &C, unsigned NumElts) const
Exposes information about the current target.
Definition: TargetInfo.h:54
bool isObjCRetainableType() const
Definition: Type.cpp:3921
CanQualType ShortTy
Definition: ASTContext.h:1025
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:1844
virtual void HandleNullChar(const char *nullCharacter)
Definition: FormatString.h:682
Represents a GCC generic vector type.
Definition: Type.h:3171
CanQualType SignedCharTy
Definition: ASTContext.h:1025
CanQualType getUIntMaxType() const
Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in <stdint.h>.
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:700
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:4399
void setIsPrivate(const char *position)
Definition: FormatString.h:536
QualType getElementType() const
Definition: Type.h:3206
CanQualType getSignedSizeType() const
Return the unique signed counterpart of the integer type corresponding to size_t. ...
void setHasThousandsGrouping(const char *position)
Definition: FormatString.h:515
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
Definition: Type.cpp:1823
bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
const PrintfConversionSpecifier & getConversionSpecifier() const
Definition: FormatString.h:545
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:712
CanQualType UnsignedShortTy
Definition: ASTContext.h:1026
Dataflow Directional Tag Classes.
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1027
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&#39;t go fur...
Common components of both fprintf and fscanf format strings.
Definition: FormatString.h:30
void setHasObjCTechnicalTerm(const char *position)
Definition: FormatString.h:533
CanQualType UnsignedLongTy
Definition: ASTContext.h:1026
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...
void setHasPlusPrefix(const char *position)
Definition: FormatString.h:521
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:691
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
This class is used for builtin types like &#39;int&#39;.
Definition: Type.h:2394
Defines the clang::TargetInfo interface.
CanQualType IntTy
Definition: ASTContext.h:1025
unsigned getNumElements() const
Definition: Type.h:3207
bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)
bool isPointerType() const
Definition: Type.h:6299
void setHasAlternativeForm(const char *position)
Definition: FormatString.h:527
void setIsSensitive(const char *position)
Definition: FormatString.h:538
clang::analyze_format_string::SpecifierResult< PrintfSpecifier > PrintfSpecifierResult
CanQualType getIntMaxType() const
Return the unique type for "intmax_t" (C99 7.18.1.5), defined in <stdint.h>.
CanQualType DoubleTy
Definition: ASTContext.h:1028
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:1026
OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start, const char *&Beg, const char *E, PositionContext p)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.