clang  8.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  // Look for the length modifier.
251  if (ParseLengthModifier(FS, I, E, LO) && I == E) {
252  // No more characters left?
253  if (Warn)
254  H.HandleIncompleteSpecifier(Start, E - Start);
255  return true;
256  }
257 
258  // Look for the Objective-C modifier flags, if any.
259  // We parse these here, even if they don't apply to
260  // the conversion specifier, and then emit an error
261  // later if the conversion specifier isn't '@'. This
262  // enables better recovery, and we don't know if
263  // these flags are applicable until later.
264  const char *ObjCModifierFlagsStart = nullptr,
265  *ObjCModifierFlagsEnd = nullptr;
266  if (*I == '[') {
267  ObjCModifierFlagsStart = I;
268  ++I;
269  auto flagStart = I;
270  for (;; ++I) {
271  ObjCModifierFlagsEnd = I;
272  if (I == E) {
273  if (Warn)
274  H.HandleIncompleteSpecifier(Start, E - Start);
275  return true;
276  }
277  // Did we find the closing ']'?
278  if (*I == ']') {
279  if (ParseObjCFlags(H, FS, flagStart, I, Warn))
280  return true;
281  ++I;
282  break;
283  }
284  // There are no separators defined yet for multiple
285  // Objective-C modifier flags. When those are
286  // defined, this is the place to check.
287  }
288  }
289 
290  if (*I == '\0') {
291  // Detect spurious null characters, which are likely errors.
292  H.HandleNullChar(I);
293  return true;
294  }
295 
296  // Finally, look for the conversion specifier.
297  const char *conversionPosition = I++;
299  switch (*conversionPosition) {
300  default:
301  break;
302  // C99: 7.19.6.1 (section 8).
303  case '%': k = ConversionSpecifier::PercentArg; break;
304  case 'A': k = ConversionSpecifier::AArg; break;
305  case 'E': k = ConversionSpecifier::EArg; break;
306  case 'F': k = ConversionSpecifier::FArg; break;
307  case 'G': k = ConversionSpecifier::GArg; break;
308  case 'X': k = ConversionSpecifier::XArg; break;
309  case 'a': k = ConversionSpecifier::aArg; break;
310  case 'c': k = ConversionSpecifier::cArg; break;
311  case 'd': k = ConversionSpecifier::dArg; break;
312  case 'e': k = ConversionSpecifier::eArg; break;
313  case 'f': k = ConversionSpecifier::fArg; break;
314  case 'g': k = ConversionSpecifier::gArg; break;
315  case 'i': k = ConversionSpecifier::iArg; break;
316  case 'n': k = ConversionSpecifier::nArg; break;
317  case 'o': k = ConversionSpecifier::oArg; break;
318  case 'p': k = ConversionSpecifier::pArg; break;
319  case 's': k = ConversionSpecifier::sArg; break;
320  case 'u': k = ConversionSpecifier::uArg; break;
321  case 'x': k = ConversionSpecifier::xArg; break;
322  // POSIX specific.
323  case 'C': k = ConversionSpecifier::CArg; break;
324  case 'S': k = ConversionSpecifier::SArg; break;
325  // Apple extension for os_log
326  case 'P':
328  break;
329  // Objective-C.
330  case '@': k = ConversionSpecifier::ObjCObjArg; break;
331  // Glibc specific.
332  case 'm': k = ConversionSpecifier::PrintErrno; break;
333  // FreeBSD kernel specific.
334  case 'b':
335  if (isFreeBSDKPrintf)
336  k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
337  break;
338  case 'r':
339  if (isFreeBSDKPrintf)
341  break;
342  case 'y':
343  if (isFreeBSDKPrintf)
345  break;
346  // Apple-specific.
347  case 'D':
348  if (isFreeBSDKPrintf)
349  k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
350  else if (Target.getTriple().isOSDarwin())
352  break;
353  case 'O':
354  if (Target.getTriple().isOSDarwin())
356  break;
357  case 'U':
358  if (Target.getTriple().isOSDarwin())
360  break;
361  // MS specific.
362  case 'Z':
363  if (Target.getTriple().isOSMSVCRT())
365  break;
366  // OpenCL specific.
367  case 'v':
368  if (LO.OpenCL)
370  break;
371  }
372 
373  // Check to see if we used the Objective-C modifier flags with
374  // a conversion specifier other than '@'.
377  ObjCModifierFlagsStart) {
378  H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
379  ObjCModifierFlagsEnd + 1,
380  conversionPosition);
381  return true;
382  }
383 
384  PrintfConversionSpecifier CS(conversionPosition, k);
385  FS.setConversionSpecifier(CS);
386  if (CS.consumesDataArgument() && !FS.usesPositionalArg())
387  FS.setArgIndex(argIndex++);
388  // FreeBSD kernel specific.
391  argIndex++;
392 
394  unsigned Len = I - Start;
395  if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
396  CS.setEndScanList(Start + Len);
397  FS.setConversionSpecifier(CS);
398  }
399  // Assume the conversion takes one argument.
400  return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
401  }
402  return PrintfSpecifierResult(Start, FS);
403 }
404 
406  const char *I,
407  const char *E,
408  const LangOptions &LO,
409  const TargetInfo &Target,
410  bool isFreeBSDKPrintf) {
411 
412  unsigned argIndex = 0;
413 
414  // Keep looking for a format specifier until we have exhausted the string.
415  while (I != E) {
416  const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
417  LO, Target, true,
418  isFreeBSDKPrintf);
419  // Did a fail-stop error of any kind occur when parsing the specifier?
420  // If so, don't do any more processing.
421  if (FSR.shouldStop())
422  return true;
423  // Did we exhaust the string or encounter an error that
424  // we can recover from?
425  if (!FSR.hasValue())
426  continue;
427  // We have a format specifier. Pass it to the callback.
428  if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
429  I - FSR.getStart()))
430  return true;
431  }
432  assert(I == E && "Format string not exhausted");
433  return false;
434 }
435 
437  const char *E,
438  const LangOptions &LO,
439  const TargetInfo &Target) {
440 
441  unsigned argIndex = 0;
442 
443  // Keep looking for a %s format specifier until we have exhausted the string.
445  while (I != E) {
446  const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
447  LO, Target, false,
448  false);
449  // Did a fail-stop error of any kind occur when parsing the specifier?
450  // If so, don't do any more processing.
451  if (FSR.shouldStop())
452  return false;
453  // Did we exhaust the string or encounter an error that
454  // we can recover from?
455  if (!FSR.hasValue())
456  continue;
457  const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
458  // Return true if this a %s format specifier.
459  if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
460  return true;
461  }
462  return false;
463 }
464 
465 //===----------------------------------------------------------------------===//
466 // Methods on PrintfSpecifier.
467 //===----------------------------------------------------------------------===//
468 
469 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
470  bool IsObjCLiteral) const {
471  const PrintfConversionSpecifier &CS = getConversionSpecifier();
472 
473  if (!CS.consumesDataArgument())
474  return ArgType::Invalid();
475 
477  switch (LM.getKind()) {
479  return Ctx.IntTy;
482  return ArgType(ArgType::WIntTy, "wint_t");
484  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
485  return Ctx.IntTy;
486  LLVM_FALLTHROUGH;
487  default:
488  return ArgType::Invalid();
489  }
490 
491  if (CS.isIntArg())
492  switch (LM.getKind()) {
494  // GNU extension.
495  return Ctx.LongLongTy;
497  return Ctx.IntTy;
499  return ArgType(Ctx.IntTy, "__int32");
501  case LengthModifier::AsShort: return Ctx.ShortTy;
502  case LengthModifier::AsLong: return Ctx.LongTy;
505  return Ctx.LongLongTy;
507  return ArgType(Ctx.LongLongTy, "__int64");
509  return ArgType(Ctx.getIntMaxType(), "intmax_t");
511  return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
513  return Ctx.getTargetInfo().getTriple().isArch64Bit()
514  ? ArgType(Ctx.LongLongTy, "__int64")
515  : ArgType(Ctx.IntTy, "__int32");
517  return ArgType::makePtrdiffT(
518  ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
522  return ArgType::Invalid();
523  }
524 
525  if (CS.isUIntArg())
526  switch (LM.getKind()) {
528  // GNU extension.
529  return Ctx.UnsignedLongLongTy;
531  return Ctx.UnsignedIntTy;
533  return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
534  case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
535  case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
536  case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
539  return Ctx.UnsignedLongLongTy;
541  return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
543  return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
545  return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t"));
547  return Ctx.getTargetInfo().getTriple().isArch64Bit()
548  ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
549  : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
551  return ArgType::makePtrdiffT(
552  ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
556  return ArgType::Invalid();
557  }
558 
559  if (CS.isDoubleArg()) {
560  if (LM.getKind() == LengthModifier::AsLongDouble)
561  return Ctx.LongDoubleTy;
562  return Ctx.DoubleTy;
563  }
564 
565  if (CS.getKind() == ConversionSpecifier::nArg) {
566  switch (LM.getKind()) {
568  return ArgType::PtrTo(Ctx.IntTy);
570  return ArgType::PtrTo(Ctx.SignedCharTy);
572  return ArgType::PtrTo(Ctx.ShortTy);
574  return ArgType::PtrTo(Ctx.LongTy);
577  return ArgType::PtrTo(Ctx.LongLongTy);
579  return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
581  return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
583  return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
585  return ArgType(); // FIXME: Is this a known extension?
592  return ArgType::Invalid();
593  }
594  }
595 
596  switch (CS.getKind()) {
598  if (LM.getKind() == LengthModifier::AsWideChar) {
599  if (IsObjCLiteral)
601  "const unichar *");
602  return ArgType(ArgType::WCStrTy, "wchar_t *");
603  }
604  if (LM.getKind() == LengthModifier::AsWide)
605  return ArgType(ArgType::WCStrTy, "wchar_t *");
606  return ArgType::CStrTy;
608  if (IsObjCLiteral)
610  "const unichar *");
611  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
612  LM.getKind() == LengthModifier::AsShort)
613  return ArgType::CStrTy;
614  return ArgType(ArgType::WCStrTy, "wchar_t *");
616  if (IsObjCLiteral)
617  return ArgType(Ctx.UnsignedShortTy, "unichar");
618  if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
619  LM.getKind() == LengthModifier::AsShort)
620  return Ctx.IntTy;
621  return ArgType(Ctx.WideCharTy, "wchar_t");
624  return ArgType::CPointerTy;
626  return ArgType::ObjCPointerTy;
627  default:
628  break;
629  }
630 
631  // FIXME: Handle other cases.
632  return ArgType();
633 }
634 
635 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
636  ASTContext &Ctx, bool IsObjCLiteral) {
637  // %n is different from other conversion specifiers; don't try to fix it.
638  if (CS.getKind() == ConversionSpecifier::nArg)
639  return false;
640 
641  // Handle Objective-C objects first. Note that while the '%@' specifier will
642  // not warn for structure pointer or void pointer arguments (because that's
643  // how CoreFoundation objects are implemented), we only show a fixit for '%@'
644  // if we know it's an object (block, id, class, or __attribute__((NSObject))).
645  if (QT->isObjCRetainableType()) {
646  if (!IsObjCLiteral)
647  return false;
648 
650 
651  // Disable irrelevant flags
652  HasThousandsGrouping = false;
653  HasPlusPrefix = false;
654  HasSpacePrefix = false;
655  HasAlternativeForm = false;
656  HasLeadingZeroes = false;
657  Precision.setHowSpecified(OptionalAmount::NotSpecified);
658  LM.setKind(LengthModifier::None);
659 
660  return true;
661  }
662 
663  // Handle strings next (char *, wchar_t *)
664  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
665  CS.setKind(ConversionSpecifier::sArg);
666 
667  // Disable irrelevant flags
668  HasAlternativeForm = 0;
669  HasLeadingZeroes = 0;
670 
671  // Set the long length modifier for wide characters
672  if (QT->getPointeeType()->isWideCharType())
673  LM.setKind(LengthModifier::AsWideChar);
674  else
675  LM.setKind(LengthModifier::None);
676 
677  return true;
678  }
679 
680  // If it's an enum, get its underlying type.
681  if (const EnumType *ETy = QT->getAs<EnumType>())
682  QT = ETy->getDecl()->getIntegerType();
683 
684  // We can only work with builtin types.
685  const BuiltinType *BT = QT->getAs<BuiltinType>();
686  if (!BT)
687  return false;
688 
689  // Set length modifier
690  switch (BT->getKind()) {
691  case BuiltinType::Bool:
692  case BuiltinType::WChar_U:
693  case BuiltinType::WChar_S:
694  case BuiltinType::Char8: // FIXME: Treat like 'char'?
695  case BuiltinType::Char16:
696  case BuiltinType::Char32:
697  case BuiltinType::UInt128:
698  case BuiltinType::Int128:
699  case BuiltinType::Half:
700  case BuiltinType::Float16:
701  case BuiltinType::Float128:
702  case BuiltinType::ShortAccum:
703  case BuiltinType::Accum:
704  case BuiltinType::LongAccum:
705  case BuiltinType::UShortAccum:
706  case BuiltinType::UAccum:
707  case BuiltinType::ULongAccum:
708  case BuiltinType::ShortFract:
709  case BuiltinType::Fract:
710  case BuiltinType::LongFract:
711  case BuiltinType::UShortFract:
712  case BuiltinType::UFract:
713  case BuiltinType::ULongFract:
714  case BuiltinType::SatShortAccum:
715  case BuiltinType::SatAccum:
716  case BuiltinType::SatLongAccum:
717  case BuiltinType::SatUShortAccum:
718  case BuiltinType::SatUAccum:
719  case BuiltinType::SatULongAccum:
720  case BuiltinType::SatShortFract:
721  case BuiltinType::SatFract:
722  case BuiltinType::SatLongFract:
723  case BuiltinType::SatUShortFract:
724  case BuiltinType::SatUFract:
725  case BuiltinType::SatULongFract:
726  // Various types which are non-trivial to correct.
727  return false;
728 
729 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
730  case BuiltinType::Id:
731 #include "clang/Basic/OpenCLImageTypes.def"
732 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
733  case BuiltinType::Id:
734 #include "clang/Basic/OpenCLExtensionTypes.def"
735 #define SIGNED_TYPE(Id, SingletonId)
736 #define UNSIGNED_TYPE(Id, SingletonId)
737 #define FLOATING_TYPE(Id, SingletonId)
738 #define BUILTIN_TYPE(Id, SingletonId) \
739  case BuiltinType::Id:
740 #include "clang/AST/BuiltinTypes.def"
741  // Misc other stuff which doesn't make sense here.
742  return false;
743 
744  case BuiltinType::UInt:
745  case BuiltinType::Int:
746  case BuiltinType::Float:
747  case BuiltinType::Double:
748  LM.setKind(LengthModifier::None);
749  break;
750 
751  case BuiltinType::Char_U:
752  case BuiltinType::UChar:
753  case BuiltinType::Char_S:
754  case BuiltinType::SChar:
755  LM.setKind(LengthModifier::AsChar);
756  break;
757 
758  case BuiltinType::Short:
759  case BuiltinType::UShort:
760  LM.setKind(LengthModifier::AsShort);
761  break;
762 
763  case BuiltinType::Long:
764  case BuiltinType::ULong:
765  LM.setKind(LengthModifier::AsLong);
766  break;
767 
768  case BuiltinType::LongLong:
769  case BuiltinType::ULongLong:
770  LM.setKind(LengthModifier::AsLongLong);
771  break;
772 
773  case BuiltinType::LongDouble:
774  LM.setKind(LengthModifier::AsLongDouble);
775  break;
776  }
777 
778  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
779  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
780  namedTypeToLengthModifier(QT, LM);
781 
782  // If fixing the length modifier was enough, we might be done.
783  if (hasValidLengthModifier(Ctx.getTargetInfo())) {
784  // If we're going to offer a fix anyway, make sure the sign matches.
785  switch (CS.getKind()) {
788  if (QT->isSignedIntegerType())
790  break;
794  if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
796  break;
797  default:
798  // Other specifiers do not have signed/unsigned variants.
799  break;
800  }
801 
802  const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
803  if (ATR.isValid() && ATR.matchesType(Ctx, QT))
804  return true;
805  }
806 
807  // Set conversion specifier and disable any flags which do not apply to it.
808  // Let typedefs to char fall through to int, as %c is silly for uint8_t.
809  if (!isa<TypedefType>(QT) && QT->isCharType()) {
810  CS.setKind(ConversionSpecifier::cArg);
811  LM.setKind(LengthModifier::None);
812  Precision.setHowSpecified(OptionalAmount::NotSpecified);
813  HasAlternativeForm = 0;
814  HasLeadingZeroes = 0;
815  HasPlusPrefix = 0;
816  }
817  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
818  else if (QT->isRealFloatingType()) {
819  CS.setKind(ConversionSpecifier::fArg);
820  }
821  else if (QT->isSignedIntegerType()) {
822  CS.setKind(ConversionSpecifier::dArg);
823  HasAlternativeForm = 0;
824  }
825  else if (QT->isUnsignedIntegerType()) {
826  CS.setKind(ConversionSpecifier::uArg);
827  HasAlternativeForm = 0;
828  HasPlusPrefix = 0;
829  } else {
830  llvm_unreachable("Unexpected type");
831  }
832 
833  return true;
834 }
835 
836 void PrintfSpecifier::toString(raw_ostream &os) const {
837  // Whilst some features have no defined order, we are using the order
838  // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
839  os << "%";
840 
841  // Positional args
842  if (usesPositionalArg()) {
843  os << getPositionalArgIndex() << "$";
844  }
845 
846  // Conversion flags
847  if (IsLeftJustified) os << "-";
848  if (HasPlusPrefix) os << "+";
849  if (HasSpacePrefix) os << " ";
850  if (HasAlternativeForm) os << "#";
851  if (HasLeadingZeroes) os << "0";
852 
853  // Minimum field width
854  FieldWidth.toString(os);
855  // Precision
856  Precision.toString(os);
857  // Length modifier
858  os << LM.toString();
859  // Conversion specifier
860  os << CS.toString();
861 }
862 
863 bool PrintfSpecifier::hasValidPlusPrefix() const {
864  if (!HasPlusPrefix)
865  return true;
866 
867  // The plus prefix only makes sense for signed conversions
868  switch (CS.getKind()) {
882  return true;
883 
884  default:
885  return false;
886  }
887 }
888 
889 bool PrintfSpecifier::hasValidAlternativeForm() const {
890  if (!HasAlternativeForm)
891  return true;
892 
893  // Alternate form flag only valid with the oxXaAeEfFgG conversions
894  switch (CS.getKind()) {
909  return true;
910 
911  default:
912  return false;
913  }
914 }
915 
916 bool PrintfSpecifier::hasValidLeadingZeros() const {
917  if (!HasLeadingZeroes)
918  return true;
919 
920  // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
921  switch (CS.getKind()) {
941  return true;
942 
943  default:
944  return false;
945  }
946 }
947 
948 bool PrintfSpecifier::hasValidSpacePrefix() const {
949  if (!HasSpacePrefix)
950  return true;
951 
952  // The space prefix only makes sense for signed conversions
953  switch (CS.getKind()) {
967  return true;
968 
969  default:
970  return false;
971  }
972 }
973 
974 bool PrintfSpecifier::hasValidLeftJustified() const {
975  if (!IsLeftJustified)
976  return true;
977 
978  // The left justified flag is valid for all conversions except n
979  switch (CS.getKind()) {
981  return false;
982 
983  default:
984  return true;
985  }
986 }
987 
988 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
989  if (!HasThousandsGrouping)
990  return true;
991 
992  switch (CS.getKind()) {
1002  return true;
1003  default:
1004  return false;
1005  }
1006 }
1007 
1008 bool PrintfSpecifier::hasValidPrecision() const {
1009  if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
1010  return true;
1011 
1012  // Precision is only valid with the diouxXaAeEfFgGsP conversions
1013  switch (CS.getKind()) {
1036  return true;
1037 
1038  default:
1039  return false;
1040  }
1041 }
1042 bool PrintfSpecifier::hasValidFieldWidth() const {
1043  if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
1044  return true;
1045 
1046  // The field width is valid for all conversions except n
1047  switch (CS.getKind()) {
1049  return false;
1050 
1051  default:
1052  return true;
1053  }
1054 }
QualType withConst() const
Retrieves a version of this type with const applied.
CanQualType LongLongTy
Definition: ASTContext.h:1024
static ArgType makePtrdiffT(const ArgType &A)
Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t type.
Definition: FormatString.h:298
A (possibly-)qualified type.
Definition: Type.h:642
void setIsPublic(const char *position)
Definition: FormatString.h:519
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
Kind getKind() const
Definition: Type.h:2424
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:497
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:1929
virtual void HandleInvalidObjCModifierFlag(const char *startFlag, unsigned flagLen)
Definition: FormatString.h:679
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:1024
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:689
void setHasLeadingZeros(const char *position)
Definition: FormatString.h:512
CanQualType WideCharTy
Definition: ASTContext.h:1019
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:1876
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6716
virtual void HandleEmptyObjCModifierFlag(const char *startFlags, unsigned flagsLen)
Definition: FormatString.h:676
bool isWideCharType() const
Definition: Type.cpp:1788
void setPrecision(const OptionalAmount &Amt)
Definition: FormatString.h:531
static ArgType makeSizeT(const ArgType &A)
Create an ArgType which corresponds to the size_t/ssize_t type.
Definition: FormatString.h:290
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
Pieces specific to fprintf format strings.
Definition: FormatString.h:445
bool isCharType() const
Definition: Type.cpp:1779
void setHasSpacePrefix(const char *position)
Definition: FormatString.h:506
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:494
virtual bool HandleInvalidPrintfConversionSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:687
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:1027
void setIsLeftJustified(const char *position)
Definition: FormatString.h:500
virtual void handleInvalidMaskType(StringRef MaskType)
Handle mask types whose sizes are not between one and eight bytes.
Definition: FormatString.h:701
CanQualType UnsignedCharTy
Definition: ASTContext.h:1025
static ArgType PtrTo(const ArgType &A)
Create an ArgType which corresponds to the type pointer to A.
Definition: FormatString.h:282
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex)
Exposes information about the current target.
Definition: TargetInfo.h:54
bool isObjCRetainableType() const
Definition: Type.cpp:3896
CanQualType ShortTy
Definition: ASTContext.h:1024
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:1836
virtual void HandleNullChar(const char *nullCharacter)
Definition: FormatString.h:664
CanQualType SignedCharTy
Definition: ASTContext.h:1024
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:682
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:4382
void setIsPrivate(const char *position)
Definition: FormatString.h:518
CanQualType getSignedSizeType() const
Return the unique signed counterpart of the integer type corresponding to size_t. ...
void setHasThousandsGrouping(const char *position)
Definition: FormatString.h:497
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
Definition: Type.cpp:1815
bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
const PrintfConversionSpecifier & getConversionSpecifier() const
Definition: FormatString.h:527
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:694
CanQualType UnsignedShortTy
Definition: ASTContext.h:1025
Dataflow Directional Tag Classes.
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1026
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
std::string toString(const til::SExpr *E)
void setHasObjCTechnicalTerm(const char *position)
Definition: FormatString.h:515
CanQualType UnsignedLongTy
Definition: ASTContext.h:1025
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:503
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:673
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:2397
Defines the clang::TargetInfo interface.
CanQualType IntTy
Definition: ASTContext.h:1024
bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)
bool isPointerType() const
Definition: Type.h:6282
void setHasAlternativeForm(const char *position)
Definition: FormatString.h:509
void setIsSensitive(const char *position)
Definition: FormatString.h:520
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:1027
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:1025
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>.