clang  16.0.0git
FormatString.cpp
Go to the documentation of this file.
1 // FormatString.cpp - Common stuff for handling printf/scanf formats -*- 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 // Shared details for processing format strings of printf and scanf
10 // (and friends).
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "FormatStringParsing.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "llvm/Support/ConvertUTF.h"
18 
25 using namespace clang;
26 
27 // Key function to FormatStringHandler.
28 FormatStringHandler::~FormatStringHandler() {}
29 
30 //===----------------------------------------------------------------------===//
31 // Functions for parsing format strings components in both printf and
32 // scanf format strings.
33 //===----------------------------------------------------------------------===//
34 
36 clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
37  const char *I = Beg;
38  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
39 
40  unsigned accumulator = 0;
41  bool hasDigits = false;
42 
43  for ( ; I != E; ++I) {
44  char c = *I;
45  if (c >= '0' && c <= '9') {
46  hasDigits = true;
47  accumulator = (accumulator * 10) + (c - '0');
48  continue;
49  }
50 
51  if (hasDigits)
52  return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
53  false);
54 
55  break;
56  }
57 
58  return OptionalAmount();
59 }
60 
63  const char *E,
64  unsigned &argIndex) {
65  if (*Beg == '*') {
66  ++Beg;
67  return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
68  }
69 
70  return ParseAmount(Beg, E);
71 }
72 
75  const char *Start,
76  const char *&Beg,
77  const char *E,
78  PositionContext p) {
79  if (*Beg == '*') {
80  const char *I = Beg + 1;
81  const OptionalAmount &Amt = ParseAmount(I, E);
82 
83  if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
84  H.HandleInvalidPosition(Beg, I - Beg, p);
85  return OptionalAmount(false);
86  }
87 
88  if (I == E) {
89  // No more characters left?
90  H.HandleIncompleteSpecifier(Start, E - Start);
91  return OptionalAmount(false);
92  }
93 
94  assert(Amt.getHowSpecified() == OptionalAmount::Constant);
95 
96  if (*I == '$') {
97  // Handle positional arguments
98 
99  // Special case: '*0$', since this is an easy mistake.
100  if (Amt.getConstantAmount() == 0) {
101  H.HandleZeroPosition(Beg, I - Beg + 1);
102  return OptionalAmount(false);
103  }
104 
105  const char *Tmp = Beg;
106  Beg = ++I;
107 
108  return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
109  Tmp, 0, true);
110  }
111 
112  H.HandleInvalidPosition(Beg, I - Beg, p);
113  return OptionalAmount(false);
114  }
115 
116  return ParseAmount(Beg, E);
117 }
118 
119 
120 bool
122  FormatSpecifier &CS,
123  const char *Start,
124  const char *&Beg, const char *E,
125  unsigned *argIndex) {
126  // FIXME: Support negative field widths.
127  if (argIndex) {
128  CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
129  }
130  else {
131  const OptionalAmount Amt =
132  ParsePositionAmount(H, Start, Beg, E,
134 
135  if (Amt.isInvalid())
136  return true;
137  CS.setFieldWidth(Amt);
138  }
139  return false;
140 }
141 
142 bool
144  FormatSpecifier &FS,
145  const char *Start,
146  const char *&Beg,
147  const char *E) {
148  const char *I = Beg;
149 
150  const OptionalAmount &Amt = ParseAmount(I, E);
151 
152  if (I == E) {
153  // No more characters left?
154  H.HandleIncompleteSpecifier(Start, E - Start);
155  return true;
156  }
157 
158  if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
159  // Warn that positional arguments are non-standard.
160  H.HandlePosition(Start, I - Start);
161 
162  // Special case: '%0$', since this is an easy mistake.
163  if (Amt.getConstantAmount() == 0) {
164  H.HandleZeroPosition(Start, I - Start);
165  return true;
166  }
167 
168  FS.setArgIndex(Amt.getConstantAmount() - 1);
169  FS.setUsesPositionalArg();
170  // Update the caller's pointer if we decided to consume
171  // these characters.
172  Beg = I;
173  return false;
174  }
175 
176  return false;
177 }
178 
179 bool
181  FormatSpecifier &FS,
182  const char *&I,
183  const char *E,
184  const LangOptions &LO) {
185  if (!LO.OpenCL)
186  return false;
187 
188  const char *Start = I;
189  if (*I == 'v') {
190  ++I;
191 
192  if (I == E) {
193  H.HandleIncompleteSpecifier(Start, E - Start);
194  return true;
195  }
196 
197  OptionalAmount NumElts = ParseAmount(I, E);
198  if (NumElts.getHowSpecified() != OptionalAmount::Constant) {
199  H.HandleIncompleteSpecifier(Start, E - Start);
200  return true;
201  }
202 
203  FS.setVectorNumElts(NumElts);
204  }
205 
206  return false;
207 }
208 
209 bool
211  const char *&I,
212  const char *E,
213  const LangOptions &LO,
214  bool IsScanf) {
216  const char *lmPosition = I;
217  switch (*I) {
218  default:
219  return false;
220  case 'h':
221  ++I;
222  if (I != E && *I == 'h') {
223  ++I;
224  lmKind = LengthModifier::AsChar;
225  } else if (I != E && *I == 'l' && LO.OpenCL) {
226  ++I;
227  lmKind = LengthModifier::AsShortLong;
228  } else {
229  lmKind = LengthModifier::AsShort;
230  }
231  break;
232  case 'l':
233  ++I;
234  if (I != E && *I == 'l') {
235  ++I;
236  lmKind = LengthModifier::AsLongLong;
237  } else {
238  lmKind = LengthModifier::AsLong;
239  }
240  break;
241  case 'j': lmKind = LengthModifier::AsIntMax; ++I; break;
242  case 'z': lmKind = LengthModifier::AsSizeT; ++I; break;
243  case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break;
244  case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
245  case 'q': lmKind = LengthModifier::AsQuad; ++I; break;
246  case 'a':
247  if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
248  // For scanf in C90, look at the next character to see if this should
249  // be parsed as the GNU extension 'a' length modifier. If not, this
250  // will be parsed as a conversion specifier.
251  ++I;
252  if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
253  lmKind = LengthModifier::AsAllocate;
254  break;
255  }
256  --I;
257  }
258  return false;
259  case 'm':
260  if (IsScanf) {
261  lmKind = LengthModifier::AsMAllocate;
262  ++I;
263  break;
264  }
265  return false;
266  // printf: AsInt64, AsInt32, AsInt3264
267  // scanf: AsInt64
268  case 'I':
269  if (I + 1 != E && I + 2 != E) {
270  if (I[1] == '6' && I[2] == '4') {
271  I += 3;
272  lmKind = LengthModifier::AsInt64;
273  break;
274  }
275  if (IsScanf)
276  return false;
277 
278  if (I[1] == '3' && I[2] == '2') {
279  I += 3;
280  lmKind = LengthModifier::AsInt32;
281  break;
282  }
283  }
284  ++I;
285  lmKind = LengthModifier::AsInt3264;
286  break;
287  case 'w':
288  lmKind = LengthModifier::AsWide; ++I; break;
289  }
290  LengthModifier lm(lmPosition, lmKind);
291  FS.setLengthModifier(lm);
292  return true;
293 }
294 
296  const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
297  if (SpecifierBegin + 1 >= FmtStrEnd)
298  return false;
299 
300  const llvm::UTF8 *SB =
301  reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1);
302  const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd);
303  const char FirstByte = *SB;
304 
305  // If the invalid specifier is a multibyte UTF-8 string, return the
306  // total length accordingly so that the conversion specifier can be
307  // properly updated to reflect a complete UTF-8 specifier.
308  unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte);
309  if (NumBytes == 1)
310  return false;
311  if (SB + NumBytes > SE)
312  return false;
313 
314  Len = NumBytes + 1;
315  return true;
316 }
317 
318 //===----------------------------------------------------------------------===//
319 // Methods on ArgType.
320 //===----------------------------------------------------------------------===//
321 
323 ArgType::matchesType(ASTContext &C, QualType argTy) const {
324  // When using the format attribute in C++, you can receive a function or an
325  // array that will necessarily decay to a pointer when passed to the final
326  // format consumer. Apply decay before type comparison.
327  if (argTy->canDecayToPointerType())
328  argTy = C.getDecayedType(argTy);
329 
330  if (Ptr) {
331  // It has to be a pointer.
332  const PointerType *PT = argTy->getAs<PointerType>();
333  if (!PT)
334  return NoMatch;
335 
336  // We cannot write through a const qualified pointer.
337  if (PT->getPointeeType().isConstQualified())
338  return NoMatch;
339 
340  argTy = PT->getPointeeType();
341  }
342 
343  switch (K) {
344  case InvalidTy:
345  llvm_unreachable("ArgType must be valid");
346 
347  case UnknownTy:
348  return Match;
349 
350  case AnyCharTy: {
351  if (const auto *ETy = argTy->getAs<EnumType>()) {
352  // If the enum is incomplete we know nothing about the underlying type.
353  // Assume that it's 'int'.
354  if (!ETy->getDecl()->isComplete())
355  return NoMatch;
356  argTy = ETy->getDecl()->getIntegerType();
357  }
358 
359  if (const auto *BT = argTy->getAs<BuiltinType>()) {
360  // The types are perfectly matched?
361  switch (BT->getKind()) {
362  default:
363  break;
364  case BuiltinType::Char_S:
365  case BuiltinType::SChar:
366  case BuiltinType::UChar:
367  case BuiltinType::Char_U:
368  case BuiltinType::Bool:
369  return Match;
370  }
371  // "Partially matched" because of promotions?
372  if (!Ptr) {
373  switch (BT->getKind()) {
374  default:
375  break;
376  case BuiltinType::Int:
377  case BuiltinType::UInt:
378  return MatchPromotion;
379  case BuiltinType::Short:
380  case BuiltinType::UShort:
381  case BuiltinType::WChar_S:
382  case BuiltinType::WChar_U:
383  return NoMatchPromotionTypeConfusion;
384  }
385  }
386  }
387  return NoMatch;
388  }
389 
390  case SpecificTy: {
391  if (const EnumType *ETy = argTy->getAs<EnumType>()) {
392  // If the enum is incomplete we know nothing about the underlying type.
393  // Assume that it's 'int'.
394  if (!ETy->getDecl()->isComplete())
395  argTy = C.IntTy;
396  else
397  argTy = ETy->getDecl()->getIntegerType();
398  }
399  argTy = C.getCanonicalType(argTy).getUnqualifiedType();
400 
401  if (T == argTy)
402  return Match;
403  if (const auto *BT = argTy->getAs<BuiltinType>()) {
404  // Check if the only difference between them is signed vs unsigned
405  // if true, we consider they are compatible.
406  switch (BT->getKind()) {
407  default:
408  break;
409  case BuiltinType::Char_S:
410  case BuiltinType::SChar:
411  case BuiltinType::Char_U:
412  case BuiltinType::UChar:
413  case BuiltinType::Bool:
414  if (T == C.UnsignedShortTy || T == C.ShortTy)
415  return NoMatchTypeConfusion;
416  if (T == C.UnsignedCharTy || T == C.SignedCharTy)
417  return Match;
418  break;
419  case BuiltinType::Short:
420  if (T == C.UnsignedShortTy)
421  return Match;
422  break;
423  case BuiltinType::UShort:
424  if (T == C.ShortTy)
425  return Match;
426  break;
427  case BuiltinType::Int:
428  if (T == C.UnsignedIntTy)
429  return Match;
430  break;
431  case BuiltinType::UInt:
432  if (T == C.IntTy)
433  return Match;
434  break;
435  case BuiltinType::Long:
436  if (T == C.UnsignedLongTy)
437  return Match;
438  break;
439  case BuiltinType::ULong:
440  if (T == C.LongTy)
441  return Match;
442  break;
443  case BuiltinType::LongLong:
444  if (T == C.UnsignedLongLongTy)
445  return Match;
446  break;
447  case BuiltinType::ULongLong:
448  if (T == C.LongLongTy)
449  return Match;
450  break;
451  }
452  // "Partially matched" because of promotions?
453  if (!Ptr) {
454  switch (BT->getKind()) {
455  default:
456  break;
457  case BuiltinType::Int:
458  case BuiltinType::UInt:
459  if (T == C.SignedCharTy || T == C.UnsignedCharTy ||
460  T == C.ShortTy || T == C.UnsignedShortTy || T == C.WCharTy ||
461  T == C.WideCharTy)
462  return MatchPromotion;
463  break;
464  case BuiltinType::Short:
465  case BuiltinType::UShort:
466  if (T == C.SignedCharTy || T == C.UnsignedCharTy)
467  return NoMatchPromotionTypeConfusion;
468  break;
469  case BuiltinType::WChar_U:
470  case BuiltinType::WChar_S:
471  if (T != C.WCharTy && T != C.WideCharTy)
472  return NoMatchPromotionTypeConfusion;
473  }
474  }
475  }
476  return NoMatch;
477  }
478 
479  case CStrTy: {
480  const PointerType *PT = argTy->getAs<PointerType>();
481  if (!PT)
482  return NoMatch;
483  QualType pointeeTy = PT->getPointeeType();
484  if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
485  switch (BT->getKind()) {
486  case BuiltinType::Char_U:
487  case BuiltinType::UChar:
488  case BuiltinType::Char_S:
489  case BuiltinType::SChar:
490  return Match;
491  default:
492  break;
493  }
494 
495  return NoMatch;
496  }
497 
498  case WCStrTy: {
499  const PointerType *PT = argTy->getAs<PointerType>();
500  if (!PT)
501  return NoMatch;
502  QualType pointeeTy =
503  C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
504  return pointeeTy == C.getWideCharType() ? Match : NoMatch;
505  }
506 
507  case WIntTy: {
508  QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
509 
510  if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
511  return Match;
512 
513  QualType PromoArg = C.isPromotableIntegerType(argTy)
514  ? C.getPromotedIntegerType(argTy)
515  : argTy;
516  PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
517 
518  // If the promoted argument is the corresponding signed type of the
519  // wint_t type, then it should match.
520  if (PromoArg->hasSignedIntegerRepresentation() &&
521  C.getCorrespondingUnsignedType(PromoArg) == WInt)
522  return Match;
523 
524  return WInt == PromoArg ? Match : NoMatch;
525  }
526 
527  case CPointerTy:
528  if (argTy->isVoidPointerType()) {
529  return Match;
530  } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
531  argTy->isBlockPointerType() || argTy->isNullPtrType()) {
532  return NoMatchPedantic;
533  } else {
534  return NoMatch;
535  }
536 
537  case ObjCPointerTy: {
538  if (argTy->getAs<ObjCObjectPointerType>() ||
539  argTy->getAs<BlockPointerType>())
540  return Match;
541 
542  // Handle implicit toll-free bridging.
543  if (const PointerType *PT = argTy->getAs<PointerType>()) {
544  // Things such as CFTypeRef are really just opaque pointers
545  // to C structs representing CF types that can often be bridged
546  // to Objective-C objects. Since the compiler doesn't know which
547  // structs can be toll-free bridged, we just accept them all.
548  QualType pointee = PT->getPointeeType();
549  if (pointee->getAsStructureType() || pointee->isVoidType())
550  return Match;
551  }
552  return NoMatch;
553  }
554  }
555 
556  llvm_unreachable("Invalid ArgType Kind!");
557 }
558 
559 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
560  // Check for valid vector element types.
561  if (T.isNull())
562  return ArgType::Invalid();
563 
564  QualType Vec = C.getExtVectorType(T, NumElts);
565  return ArgType(Vec, Name);
566 }
567 
568 QualType ArgType::getRepresentativeType(ASTContext &C) const {
569  QualType Res;
570  switch (K) {
571  case InvalidTy:
572  llvm_unreachable("No representative type for Invalid ArgType");
573  case UnknownTy:
574  llvm_unreachable("No representative type for Unknown ArgType");
575  case AnyCharTy:
576  Res = C.CharTy;
577  break;
578  case SpecificTy:
579  Res = T;
580  break;
581  case CStrTy:
582  Res = C.getPointerType(C.CharTy);
583  break;
584  case WCStrTy:
585  Res = C.getPointerType(C.getWideCharType());
586  break;
587  case ObjCPointerTy:
588  Res = C.ObjCBuiltinIdTy;
589  break;
590  case CPointerTy:
591  Res = C.VoidPtrTy;
592  break;
593  case WIntTy: {
594  Res = C.getWIntType();
595  break;
596  }
597  }
598 
599  if (Ptr)
600  Res = C.getPointerType(Res);
601  return Res;
602 }
603 
604 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
605  std::string S = getRepresentativeType(C).getAsString(C.getPrintingPolicy());
606 
607  std::string Alias;
608  if (Name) {
609  // Use a specific name for this type, e.g. "size_t".
610  Alias = Name;
611  if (Ptr) {
612  // If ArgType is actually a pointer to T, append an asterisk.
613  Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
614  }
615  // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
616  if (S == Alias)
617  Alias.clear();
618  }
619 
620  if (!Alias.empty())
621  return std::string("'") + Alias + "' (aka '" + S + "')";
622  return std::string("'") + S + "'";
623 }
624 
625 
626 //===----------------------------------------------------------------------===//
627 // Methods on OptionalAmount.
628 //===----------------------------------------------------------------------===//
629 
630 ArgType
632  return Ctx.IntTy;
633 }
634 
635 //===----------------------------------------------------------------------===//
636 // Methods on LengthModifier.
637 //===----------------------------------------------------------------------===//
638 
639 const char *
641  switch (kind) {
642  case AsChar:
643  return "hh";
644  case AsShort:
645  return "h";
646  case AsShortLong:
647  return "hl";
648  case AsLong: // or AsWideChar
649  return "l";
650  case AsLongLong:
651  return "ll";
652  case AsQuad:
653  return "q";
654  case AsIntMax:
655  return "j";
656  case AsSizeT:
657  return "z";
658  case AsPtrDiff:
659  return "t";
660  case AsInt32:
661  return "I32";
662  case AsInt3264:
663  return "I";
664  case AsInt64:
665  return "I64";
666  case AsLongDouble:
667  return "L";
668  case AsAllocate:
669  return "a";
670  case AsMAllocate:
671  return "m";
672  case AsWide:
673  return "w";
674  case None:
675  return "";
676  }
677  return nullptr;
678 }
679 
680 //===----------------------------------------------------------------------===//
681 // Methods on ConversionSpecifier.
682 //===----------------------------------------------------------------------===//
683 
684 const char *ConversionSpecifier::toString() const {
685  switch (kind) {
686  case bArg: return "b";
687  case BArg: return "B";
688  case dArg: return "d";
689  case DArg: return "D";
690  case iArg: return "i";
691  case oArg: return "o";
692  case OArg: return "O";
693  case uArg: return "u";
694  case UArg: return "U";
695  case xArg: return "x";
696  case XArg: return "X";
697  case fArg: return "f";
698  case FArg: return "F";
699  case eArg: return "e";
700  case EArg: return "E";
701  case gArg: return "g";
702  case GArg: return "G";
703  case aArg: return "a";
704  case AArg: return "A";
705  case cArg: return "c";
706  case sArg: return "s";
707  case pArg: return "p";
708  case PArg:
709  return "P";
710  case nArg: return "n";
711  case PercentArg: return "%";
712  case ScanListArg: return "[";
713  case InvalidSpecifier: return nullptr;
714 
715  // POSIX unicode extensions.
716  case CArg: return "C";
717  case SArg: return "S";
718 
719  // Objective-C specific specifiers.
720  case ObjCObjArg: return "@";
721 
722  // FreeBSD kernel specific specifiers.
723  case FreeBSDbArg: return "b";
724  case FreeBSDDArg: return "D";
725  case FreeBSDrArg: return "r";
726  case FreeBSDyArg: return "y";
727 
728  // GlibC specific specifiers.
729  case PrintErrno: return "m";
730 
731  // MS specific specifiers.
732  case ZArg: return "Z";
733  }
734  return nullptr;
735 }
736 
740 
741  switch (getKind()) {
742  default:
743  return std::nullopt;
744  case DArg:
745  NewKind = dArg;
746  break;
747  case UArg:
748  NewKind = uArg;
749  break;
750  case OArg:
751  NewKind = oArg;
752  break;
753  }
754 
755  ConversionSpecifier FixedCS(*this);
756  FixedCS.setKind(NewKind);
757  return FixedCS;
758 }
759 
760 //===----------------------------------------------------------------------===//
761 // Methods on OptionalAmount.
762 //===----------------------------------------------------------------------===//
763 
764 void OptionalAmount::toString(raw_ostream &os) const {
765  switch (hs) {
766  case Invalid:
767  case NotSpecified:
768  return;
769  case Arg:
770  if (UsesDotPrefix)
771  os << ".";
772  if (usesPositionalArg())
773  os << "*" << getPositionalArgIndex() << "$";
774  else
775  os << "*";
776  break;
777  case Constant:
778  if (UsesDotPrefix)
779  os << ".";
780  os << amt;
781  break;
782  }
783 }
784 
786  const LangOptions &LO) const {
787  switch (LM.getKind()) {
789  return true;
790 
791  // Handle most integer flags
793  // Length modifier only applies to FP vectors.
794  if (LO.OpenCL && CS.isDoubleArg())
795  return !VectorNumElts.isInvalid();
796 
797  if (Target.getTriple().isOSMSVCRT()) {
798  switch (CS.getKind()) {
804  return true;
805  default:
806  break;
807  }
808  }
809  [[fallthrough]];
816  switch (CS.getKind()) {
829  return true;
832  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS();
833  default:
834  return false;
835  }
836 
838  return LO.OpenCL && !VectorNumElts.isInvalid();
839 
840  // Handle 'l' flag
841  case LengthModifier::AsLong: // or AsWideChar
842  if (CS.isDoubleArg()) {
843  // Invalid for OpenCL FP scalars.
844  if (LO.OpenCL && VectorNumElts.isInvalid())
845  return false;
846  return true;
847  }
848 
849  switch (CS.getKind()) {
864  return true;
867  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS();
868  default:
869  return false;
870  }
871 
873  switch (CS.getKind()) {
882  return true;
883  // GNU libc extension.
890  return !Target.getTriple().isOSDarwin() &&
891  !Target.getTriple().isOSWindows();
892  default:
893  return false;
894  }
895 
897  switch (CS.getKind()) {
901  return true;
902  default:
903  return false;
904  }
905 
907  switch (CS.getKind()) {
913  return true;
914  default:
915  return false;
916  }
920  switch (CS.getKind()) {
927  return Target.getTriple().isOSMSVCRT();
928  default:
929  return false;
930  }
932  switch (CS.getKind()) {
938  return Target.getTriple().isOSMSVCRT();
939  default:
940  return false;
941  }
942  }
943  llvm_unreachable("Invalid LengthModifier Kind!");
944 }
945 
947  switch (LM.getKind()) {
957  return true;
965  case LengthModifier::AsShortLong: // ???
966  return false;
967  }
968  llvm_unreachable("Invalid LengthModifier Kind!");
969 }
970 
972  const LangOptions &LangOpt) const {
973  switch (CS.getKind()) {
998  return true;
1001  return LangOpt.ObjC;
1012  return false;
1013  }
1014  llvm_unreachable("Invalid ConversionSpecifier Kind!");
1015 }
1016 
1019  switch(CS.getKind()) {
1026  return false;
1027  default:
1028  return true;
1029  }
1030  }
1031  return true;
1032 }
1033 
1038  LengthModifier FixedLM(LM);
1040  return FixedLM;
1041  }
1042  }
1043 
1044  return std::nullopt;
1045 }
1046 
1048  LengthModifier &LM) {
1049  for (/**/; const auto *TT = QT->getAs<TypedefType>();
1050  QT = TT->getDecl()->getUnderlyingType()) {
1051  const TypedefNameDecl *Typedef = TT->getDecl();
1052  const IdentifierInfo *Identifier = Typedef->getIdentifier();
1053  if (Identifier->getName() == "size_t") {
1055  return true;
1056  } else if (Identifier->getName() == "ssize_t") {
1057  // Not C99, but common in Unix.
1059  return true;
1060  } else if (Identifier->getName() == "intmax_t") {
1062  return true;
1063  } else if (Identifier->getName() == "uintmax_t") {
1065  return true;
1066  } else if (Identifier->getName() == "ptrdiff_t") {
1068  return true;
1069  }
1070  }
1071  return false;
1072 }
clang::BuiltinType
This class is used for builtin types like 'int'.
Definition: Type.h:2620
clang::analyze_format_string::FormatSpecifier::setFieldWidth
void setFieldWidth(const OptionalAmount &Amt)
Definition: FormatString.h:458
clang::analyze_format_string::ConversionSpecifier::SArg
@ SArg
Definition: FormatString.h:162
clang::analyze_format_string::ConversionSpecifier::oArg
@ oArg
Definition: FormatString.h:137
clang::analyze_format_string::ConversionSpecifier::cArg
@ cArg
Definition: FormatString.h:126
clang::Type::isBlockPointerType
bool isBlockPointerType() const
Definition: Type.h:6891
clang::analyze_format_string::ConversionSpecifier::ObjCObjArg
@ ObjCObjArg
Definition: FormatString.h:174
clang::analyze_format_string::ConversionSpecifier::isAnyIntArg
bool isAnyIntArg() const
Definition: FormatString.h:235
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::Type::isVoidPointerType
bool isVoidPointerType() const
Definition: Type.cpp:589
clang::analyze_format_string::LengthModifier::AsMAllocate
@ AsMAllocate
Definition: FormatString.h:82
clang::analyze_format_string::LengthModifier::AsLongDouble
@ AsLongDouble
Definition: FormatString.h:80
clang::QualType::isConstQualified
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6694
clang::analyze_format_string::ConversionSpecifier::xArg
@ xArg
Definition: FormatString.h:141
clang::analyze_format_string::FormatStringHandler
Definition: FormatString.h:702
clang::analyze_format_string::FormatSpecifier
Definition: FormatString.h:407
clang::analyze_format_string::FormatSpecifier::namedTypeToLengthModifier
static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM)
For a TypedefType QT, if it is a named integer type such as size_t, assign the appropriate value to L...
Definition: FormatString.cpp:1047
TargetInfo.h
clang::MultiVersionKind::Target
@ Target
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::analyze_format_string::ConversionSpecifier::isDoubleArg
bool isDoubleArg() const
Definition: FormatString.h:236
clang::analyze_format_string::OptionalAmount::getConstantAmount
unsigned getConstantAmount() const
Definition: FormatString.h:369
clang::analyze_format_string::ConversionSpecifier::sArg
@ sArg
Definition: FormatString.h:157
clang::TargetInfo
Exposes information about the current target.
Definition: TargetInfo.h:205
clang::analyze_format_string::FormatSpecifier::CS
ConversionSpecifier CS
Definition: FormatString.h:411
clang::analyze_format_string::OptionalAmount::usesPositionalArg
bool usesPositionalArg() const
Definition: FormatString.h:388
clang::analyze_format_string::FormatStringHandler::HandleInvalidPosition
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen, PositionContext p)
Definition: FormatString.h:711
clang::analyze_format_string::LengthModifier::AsInt3264
@ AsInt3264
Definition: FormatString.h:78
llvm::Optional
Definition: LLVM.h:40
clang::Type::isVoidType
bool isVoidType() const
Definition: Type.h:7180
Identifier
StringRef Identifier
Definition: Format.cpp:2723
clang::analyze_format_string::ParsePositionAmount
OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start, const char *&Beg, const char *E, PositionContext p)
Definition: FormatString.cpp:74
clang::analyze_format_string::FormatStringHandler::HandleZeroPosition
virtual void HandleZeroPosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:714
clang::analyze_format_string::ConversionSpecifier::iArg
@ iArg
Definition: FormatString.h:129
clang::analyze_format_string::ConversionSpecifier
Definition: FormatString.h:121
clang::analyze_format_string::ArgType::MatchKind
MatchKind
How well a given conversion specifier matches its argument.
Definition: FormatString.h:259
clang::analyze_format_string::ConversionSpecifier::FArg
@ FArg
Definition: FormatString.h:147
clang::analyze_format_string::ConversionSpecifier::fArg
@ fArg
Definition: FormatString.h:146
clang::analyze_format_string::FormatSpecifier::hasValidLengthModifier
bool hasValidLengthModifier(const TargetInfo &Target, const LangOptions &LO) const
Definition: FormatString.cpp:785
clang::analyze_format_string::ConversionSpecifier::toString
const char * toString() const
Definition: FormatString.cpp:684
clang::analyze_format_string::LengthModifier::getKind
Kind getKind() const
Definition: FormatString.h:111
clang::analyze_format_string::OptionalAmount::getPositionalArgIndex
unsigned getPositionalArgIndex() const
Definition: FormatString.h:389
clang::Type::hasSignedIntegerRepresentation
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
Definition: Type.cpp:2059
clang::analyze_format_string::ConversionSpecifier::getKind
Kind getKind() const
Definition: FormatString.h:225
clang::analyze_format_string::ConversionSpecifier::FreeBSDDArg
@ FreeBSDDArg
Definition: FormatString.h:180
clang::TypedefType
Definition: Type.h:4535
clang::Type::getAsStructureType
const RecordType * getAsStructureType() const
Definition: Type.cpp:641
clang::analyze_format_string::LengthModifier::setKind
void setKind(Kind k)
Definition: FormatString.h:112
clang::analyze_format_string::OptionalAmount
Definition: FormatString.h:335
clang::analyze_format_string::OptionalAmount::Constant
@ Constant
Definition: FormatString.h:337
clang::analyze_format_string::OptionalAmount::getArgType
ArgType getArgType(ASTContext &Ctx) const
Definition: FormatString.cpp:631
clang::analyze_format_string::OptionalAmount::Arg
@ Arg
Definition: FormatString.h:337
clang::analyze_format_string::ConversionSpecifier::nArg
@ nArg
Definition: FormatString.h:159
clang::analyze_format_string::OptionalAmount::toString
void toString(raw_ostream &os) const
Definition: FormatString.cpp:764
clang::analyze_format_string::ConversionSpecifier::gArg
@ gArg
Definition: FormatString.h:150
clang::analyze_format_string::PositionContext
PositionContext
Definition: FormatString.h:700
clang::Type::isNullPtrType
bool isNullPtrType() const
Definition: Type.h:7205
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
clang::analyze_format_string::ConversionSpecifier::BArg
@ BArg
Definition: FormatString.h:132
clang::analyze_format_string::ConversionSpecifier::DArg
@ DArg
Definition: FormatString.h:128
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
LangOptions.h
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7386
clang::analyze_format_string::ParseLengthModifier
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,...
Definition: FormatString.cpp:210
clang::analyze_format_string::ConversionSpecifier::FreeBSDyArg
@ FreeBSDyArg
Definition: FormatString.h:182
FormatStringParsing.h
clang::analyze_format_string::ConversionSpecifier::bArg
@ bArg
Definition: FormatString.h:131
clang::analyze_format_string::ConversionSpecifier::dArg
@ dArg
Definition: FormatString.h:127
clang::analyze_format_string::FieldWidthPos
@ FieldWidthPos
Definition: FormatString.h:700
clang::analyze_format_string::ParseVectorModifier
bool ParseVectorModifier(FormatStringHandler &H, FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO)
Definition: FormatString.cpp:180
clang::analyze_format_string::LengthModifier::AsWide
@ AsWide
Definition: FormatString.h:83
clang::analyze_format_string::ConversionSpecifier::ScanListArg
@ ScanListArg
Definition: FormatString.h:191
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::analyze_format_string::ConversionSpecifier::kind
Kind kind
Definition: FormatString.h:250
clang::analyze_format_string::ConversionSpecifier::uArg
@ uArg
Definition: FormatString.h:139
clang::analyze_format_string::LengthModifier::AsLongLong
@ AsLongLong
Definition: FormatString.h:72
clang::analyze_format_string::LengthModifier::AsQuad
@ AsQuad
Definition: FormatString.h:73
clang::BlockPointerType
Pointer to a block type.
Definition: Type.h:2849
clang::analyze_format_string::LengthModifier::AsInt32
@ AsInt32
Definition: FormatString.h:77
clang::analyze_format_string::LengthModifier::AsIntMax
@ AsIntMax
Definition: FormatString.h:74
clang::analyze_format_string::LengthModifier::AsShort
@ AsShort
Definition: FormatString.h:69
clang::analyze_format_string::FormatSpecifier::hasStandardConversionSpecifier
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const
Definition: FormatString.cpp:971
clang::Type::isObjCObjectPointerType
bool isObjCObjectPointerType() const
Definition: Type.h:7011
clang::analyze_format_string::OptionalAmount::Invalid
@ Invalid
Definition: FormatString.h:337
clang::analyze_format_string::FormatSpecifier::hasStandardLengthConversionCombination
bool hasStandardLengthConversionCombination() const
Definition: FormatString.cpp:1017
clang::analyze_format_string::ConversionSpecifier::Kind
Kind
Definition: FormatString.h:123
clang::analyze_format_string::ParseNonPositionAmount
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex)
Definition: FormatString.cpp:62
clang::ObjCObjectPointerType
Represents a pointer to an Objective C object.
Definition: Type.h:6270
clang::analyze_format_string::LengthModifier::Kind
Kind
Definition: FormatString.h:66
clang::analyze_format_string::LengthModifier::AsSizeT
@ AsSizeT
Definition: FormatString.h:75
clang::Type::canDecayToPointerType
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
Definition: Type.h:7323
clang::analyze_format_string::ConversionSpecifier::XArg
@ XArg
Definition: FormatString.h:142
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6883
clang::analyze_format_string::ParseFieldWidth
bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
Definition: FormatString.cpp:121
clang::analyze_format_string::LengthModifier::toString
const char * toString() const
Definition: FormatString.cpp:640
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
clang::ASTContext::IntTy
CanQualType IntTy
Definition: ASTContext.h:1089
clang::analyze_format_string::ConversionSpecifier::GArg
@ GArg
Definition: FormatString.h:151
clang::analyze_format_string::OptionalAmount::getHowSpecified
HowSpecified getHowSpecified() const
Definition: FormatString.h:359
clang::analyze_format_string::ConversionSpecifier::PrintErrno
@ PrintErrno
Definition: FormatString.h:185
clang::analyze_format_string::ConversionSpecifier::PercentArg
@ PercentArg
Definition: FormatString.h:160
clang::analyze_format_string::LengthModifier::None
@ None
Definition: FormatString.h:67
clang::analyze_format_string::ConversionSpecifier::aArg
@ aArg
Definition: FormatString.h:152
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:85
clang::analyze_format_string::FormatSpecifier::LM
LengthModifier LM
Definition: FormatString.h:409
clang::analyze_format_string::ParseArgPosition
bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E)
Definition: FormatString.cpp:143
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:81
clang::analyze_format_string::FormatStringHandler::HandlePosition
virtual void HandlePosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:709
clang::analyze_format_string::ConversionSpecifier::FreeBSDrArg
@ FreeBSDrArg
Definition: FormatString.h:181
clang::analyze_format_string::ConversionSpecifier::OArg
@ OArg
Definition: FormatString.h:138
clang::UpdateOnReturn
Definition: FormatStringParsing.h:26
clang::analyze_format_string::ConversionSpecifier::PArg
@ PArg
Definition: FormatString.h:167
clang::PointerType
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2769
clang::analyze_format_string::FormatStringHandler::HandleIncompleteSpecifier
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:716
clang::analyze_format_string::OptionalAmount::isInvalid
bool isInvalid() const
Definition: FormatString.h:355
clang::analyze_format_string::ConversionSpecifier::setKind
void setKind(Kind k)
Definition: FormatString.h:226
clang
Definition: CalledOnceCheck.h:17
clang::analyze_format_string::ArgType
Definition: FormatString.h:253
clang::analyze_format_string::ConversionSpecifier::InvalidSpecifier
@ InvalidSpecifier
Definition: FormatString.h:124
clang::analyze_format_string::ConversionSpecifier::CArg
@ CArg
Definition: FormatString.h:161
clang::analyze_format_string::LengthModifier::AsAllocate
@ AsAllocate
Definition: FormatString.h:81
clang::analyze_format_string::FormatSpecifier::VectorNumElts
OptionalAmount VectorNumElts
Definition: FormatString.h:412
clang::analyze_format_string::FormatSpecifier::getCorrectedLengthModifier
Optional< LengthModifier > getCorrectedLengthModifier() const
Definition: FormatString.cpp:1034
clang::analyze_format_string::ConversionSpecifier::ZArg
@ ZArg
Definition: FormatString.h:171
clang::analyze_format_string::ConversionSpecifier::AArg
@ AArg
Definition: FormatString.h:153
clang::analyze_format_string::LengthModifier::AsChar
@ AsChar
Definition: FormatString.h:68
clang::analyze_format_string::ConversionSpecifier::pArg
@ pArg
Definition: FormatString.h:158
clang::analyze_format_string::ConversionSpecifier::UArg
@ UArg
Definition: FormatString.h:140
clang::TypedefNameDecl
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3275
clang::analyze_format_string::ParseUTF8InvalidSpecifier
bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len)
Returns true if the invalid specifier in SpecifierBegin is a UTF-8 string; check that it won't go fur...
Definition: FormatString.cpp:295
clang::analyze_format_string::FormatSpecifier::hasStandardLengthModifier
bool hasStandardLengthModifier() const
Definition: FormatString.cpp:946
c
__device__ __2f16 float c
Definition: __clang_hip_libdevice_declares.h:320
clang::PointerType::getPointeeType
QualType getPointeeType() const
Definition: Type.h:2779
clang::analyze_format_string::ConversionSpecifier::eArg
@ eArg
Definition: FormatString.h:148
clang::analyze_format_string::OptionalAmount::NotSpecified
@ NotSpecified
Definition: FormatString.h:337
clang::analyze_format_string::ConversionSpecifier::FreeBSDbArg
@ FreeBSDbArg
Definition: FormatString.h:179
clang::analyze_format_string::ConversionSpecifier::getStandardSpecifier
Optional< ConversionSpecifier > getStandardSpecifier() const
Definition: FormatString.cpp:738
clang::analyze_format_string::LengthModifier::AsShortLong
@ AsShortLong
Definition: FormatString.h:70
clang::EnumType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:4842
clang::analyze_format_string::ParseAmount
OptionalAmount ParseAmount(const char *&Beg, const char *E)
Definition: FormatString.cpp:36
clang::RISCV::Invalid
@ Invalid
Definition: RISCVVIntrinsicUtils.h:171
clang::analyze_format_string::LengthModifier
Represents the length modifier in a format string in scanf/printf.
Definition: FormatString.h:64
clang::analyze_format_string::ConversionSpecifier::EArg
@ EArg
Definition: FormatString.h:149
clang::analyze_format_string::LengthModifier::AsLong
@ AsLong
Definition: FormatString.h:71
clang::diag::kind
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:62
clang::analyze_format_string::LengthModifier::AsPtrDiff
@ AsPtrDiff
Definition: FormatString.h:76
clang::analyze_format_string::LengthModifier::AsInt64
@ AsInt64
Definition: FormatString.h:79