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