1 //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
13 //===----------------------------------------------------------------------===//
15 #include "clang/AST/FormatString.h"
16 #include "clang/AST/OSLog.h"
17 #include "FormatStringParsing.h"
18 #include "clang/Basic/TargetInfo.h"
20 using clang::analyze_format_string::ArgType;
21 using clang::analyze_format_string::FormatStringHandler;
22 using clang::analyze_format_string::LengthModifier;
23 using clang::analyze_format_string::OptionalAmount;
24 using clang::analyze_format_string::ConversionSpecifier;
25 using clang::analyze_printf::PrintfSpecifier;
27 using namespace clang;
29 typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
30 PrintfSpecifierResult;
32 //===----------------------------------------------------------------------===//
33 // Methods for parsing format strings.
34 //===----------------------------------------------------------------------===//
36 using analyze_format_string::ParseNonPositionAmount;
38 static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
39 const char *Start, const char *&Beg, const char *E,
42 FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
44 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
45 analyze_format_string::PrecisionPos);
53 static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS,
54 const char *FlagBeg, const char *E, bool Warn) {
55 StringRef Flag(FlagBeg, E - FlagBeg);
56 // Currently there is only one flag.
58 FS.setHasObjCTechnicalTerm(FlagBeg);
61 // Handle either the case of no flag or an invalid flag.
64 H.HandleEmptyObjCModifierFlag(FlagBeg, E - FlagBeg);
66 H.HandleInvalidObjCModifierFlag(FlagBeg, E - FlagBeg);
71 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
75 const LangOptions &LO,
76 const TargetInfo &Target,
78 bool isFreeBSDKPrintf) {
80 using namespace clang::analyze_format_string;
81 using namespace clang::analyze_printf;
84 const char *Start = nullptr;
85 UpdateOnReturn <const char*> UpdateBeg(Beg, I);
87 // Look for a '%' character that indicates the start of a format specifier.
88 for ( ; I != E ; ++I) {
91 // Detect spurious null characters, which are likely errors.
96 Start = I++; // Record the start of the format specifier.
101 // No format specifier found?
106 // No more characters left?
108 H.HandleIncompleteSpecifier(Start, E - Start);
113 if (ParseArgPosition(H, FS, Start, I, E))
117 // No more characters left?
119 H.HandleIncompleteSpecifier(Start, E - Start);
125 unsigned char PrivacyFlags = 0;
126 StringRef MatchedStr;
129 StringRef Str(I, E - I);
130 std::string Match = "^[[:space:]]*"
131 "(private|public|sensitive|mask\\.[^[:space:],}]*)"
133 llvm::Regex R(Match);
134 SmallVector<StringRef, 2> Matches;
136 if (R.match(Str, &Matches)) {
137 MatchedStr = Matches[1];
138 I += Matches[0].size();
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"))
150 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsSensitive;
151 else if (PrivacyFlags !=
152 clang::analyze_os_log::OSLogBufferItem::IsSensitive &&
153 MatchedStr.equals("private"))
154 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate;
155 else if (PrivacyFlags == 0 && MatchedStr.equals("public"))
156 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic;
158 size_t CommaOrBracePos =
159 Str.find_if([](char c) { return c == ',' || c == '}'; });
161 if (CommaOrBracePos == StringRef::npos) {
162 // Neither a comma nor the closing brace was found.
164 H.HandleIncompleteSpecifier(Start, E - Start);
168 I += CommaOrBracePos + 1;
170 // Continue until the closing brace is found.
171 } while (*(I - 1) == ',');
173 // Set the privacy flag.
174 switch (PrivacyFlags) {
177 case clang::analyze_os_log::OSLogBufferItem::IsPrivate:
178 FS.setIsPrivate(MatchedStr.data());
180 case clang::analyze_os_log::OSLogBufferItem::IsPublic:
181 FS.setIsPublic(MatchedStr.data());
183 case clang::analyze_os_log::OSLogBufferItem::IsSensitive:
184 FS.setIsSensitive(MatchedStr.data());
187 llvm_unreachable("Unexpected privacy flag value");
191 // Look for flags (if any).
193 for ( ; I != E; ++I) {
195 default: hasMore = false; break;
197 // FIXME: POSIX specific. Always accept?
198 FS.setHasThousandsGrouping(I);
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;
211 // No more characters left?
213 H.HandleIncompleteSpecifier(Start, E - Start);
217 // Look for the field width (if any).
218 if (ParseFieldWidth(H, FS, Start, I, E,
219 FS.usesPositionalArg() ? nullptr : &argIndex))
223 // No more characters left?
225 H.HandleIncompleteSpecifier(Start, E - Start);
229 // Look for the precision (if any).
234 H.HandleIncompleteSpecifier(Start, E - Start);
238 if (ParsePrecision(H, FS, Start, I, E,
239 FS.usesPositionalArg() ? nullptr : &argIndex))
243 // No more characters left?
245 H.HandleIncompleteSpecifier(Start, E - Start);
250 if (ParseVectorModifier(H, FS, I, E, LO))
253 // Look for the length modifier.
254 if (ParseLengthModifier(FS, I, E, LO) && I == E) {
255 // No more characters left?
257 H.HandleIncompleteSpecifier(Start, E - Start);
261 // Look for the Objective-C modifier flags, if any.
262 // We parse these here, even if they don't apply to
263 // the conversion specifier, and then emit an error
264 // later if the conversion specifier isn't '@'. This
265 // enables better recovery, and we don't know if
266 // these flags are applicable until later.
267 const char *ObjCModifierFlagsStart = nullptr,
268 *ObjCModifierFlagsEnd = nullptr;
270 ObjCModifierFlagsStart = I;
274 ObjCModifierFlagsEnd = I;
277 H.HandleIncompleteSpecifier(Start, E - Start);
280 // Did we find the closing ']'?
282 if (ParseObjCFlags(H, FS, flagStart, I, Warn))
287 // There are no separators defined yet for multiple
288 // Objective-C modifier flags. When those are
289 // defined, this is the place to check.
294 // Detect spurious null characters, which are likely errors.
299 // Finally, look for the conversion specifier.
300 const char *conversionPosition = I++;
301 ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
302 switch (*conversionPosition) {
305 // C99: 7.19.6.1 (section 8).
306 case '%': k = ConversionSpecifier::PercentArg; break;
307 case 'A': k = ConversionSpecifier::AArg; break;
308 case 'E': k = ConversionSpecifier::EArg; break;
309 case 'F': k = ConversionSpecifier::FArg; break;
310 case 'G': k = ConversionSpecifier::GArg; break;
311 case 'X': k = ConversionSpecifier::XArg; break;
312 case 'a': k = ConversionSpecifier::aArg; break;
313 case 'c': k = ConversionSpecifier::cArg; break;
314 case 'd': k = ConversionSpecifier::dArg; break;
315 case 'e': k = ConversionSpecifier::eArg; break;
316 case 'f': k = ConversionSpecifier::fArg; break;
317 case 'g': k = ConversionSpecifier::gArg; break;
318 case 'i': k = ConversionSpecifier::iArg; break;
319 case 'n': k = ConversionSpecifier::nArg; break;
320 case 'o': k = ConversionSpecifier::oArg; break;
321 case 'p': k = ConversionSpecifier::pArg; break;
322 case 's': k = ConversionSpecifier::sArg; break;
323 case 'u': k = ConversionSpecifier::uArg; break;
324 case 'x': k = ConversionSpecifier::xArg; break;
326 case 'C': k = ConversionSpecifier::CArg; break;
327 case 'S': k = ConversionSpecifier::SArg; break;
328 // Apple extension for os_log
330 k = ConversionSpecifier::PArg;
333 case '@': k = ConversionSpecifier::ObjCObjArg; break;
335 case 'm': k = ConversionSpecifier::PrintErrno; break;
336 // FreeBSD kernel specific.
338 if (isFreeBSDKPrintf)
339 k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
342 if (isFreeBSDKPrintf)
343 k = ConversionSpecifier::FreeBSDrArg; // int
346 if (isFreeBSDKPrintf)
347 k = ConversionSpecifier::FreeBSDyArg; // int
351 if (isFreeBSDKPrintf)
352 k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
353 else if (Target.getTriple().isOSDarwin())
354 k = ConversionSpecifier::DArg;
357 if (Target.getTriple().isOSDarwin())
358 k = ConversionSpecifier::OArg;
361 if (Target.getTriple().isOSDarwin())
362 k = ConversionSpecifier::UArg;
366 if (Target.getTriple().isOSMSVCRT())
367 k = ConversionSpecifier::ZArg;
371 // Check to see if we used the Objective-C modifier flags with
372 // a conversion specifier other than '@'.
373 if (k != ConversionSpecifier::ObjCObjArg &&
374 k != ConversionSpecifier::InvalidSpecifier &&
375 ObjCModifierFlagsStart) {
376 H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
377 ObjCModifierFlagsEnd + 1,
382 PrintfConversionSpecifier CS(conversionPosition, k);
383 FS.setConversionSpecifier(CS);
384 if (CS.consumesDataArgument() && !FS.usesPositionalArg())
385 FS.setArgIndex(argIndex++);
386 // FreeBSD kernel specific.
387 if (k == ConversionSpecifier::FreeBSDbArg ||
388 k == ConversionSpecifier::FreeBSDDArg)
391 if (k == ConversionSpecifier::InvalidSpecifier) {
392 unsigned Len = I - Start;
393 if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
394 CS.setEndScanList(Start + Len);
395 FS.setConversionSpecifier(CS);
397 // Assume the conversion takes one argument.
398 return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
400 return PrintfSpecifierResult(Start, FS);
403 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
406 const LangOptions &LO,
407 const TargetInfo &Target,
408 bool isFreeBSDKPrintf) {
410 unsigned argIndex = 0;
412 // Keep looking for a format specifier until we have exhausted the string.
414 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
417 // Did a fail-stop error of any kind occur when parsing the specifier?
418 // If so, don't do any more processing.
419 if (FSR.shouldStop())
421 // Did we exhaust the string or encounter an error that
422 // we can recover from?
425 // We have a format specifier. Pass it to the callback.
426 if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
430 assert(I == E && "Format string not exhausted");
434 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
436 const LangOptions &LO,
437 const TargetInfo &Target) {
439 unsigned argIndex = 0;
441 // Keep looking for a %s format specifier until we have exhausted the string.
442 FormatStringHandler H;
444 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
447 // Did a fail-stop error of any kind occur when parsing the specifier?
448 // If so, don't do any more processing.
449 if (FSR.shouldStop())
451 // Did we exhaust the string or encounter an error that
452 // we can recover from?
455 const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
456 // Return true if this a %s format specifier.
457 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
463 //===----------------------------------------------------------------------===//
464 // Methods on PrintfSpecifier.
465 //===----------------------------------------------------------------------===//
467 ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
468 bool IsObjCLiteral) const {
469 if (CS.getKind() == ConversionSpecifier::cArg)
470 switch (LM.getKind()) {
471 case LengthModifier::None:
473 case LengthModifier::AsLong:
474 case LengthModifier::AsWide:
475 return ArgType(ArgType::WIntTy, "wint_t");
476 case LengthModifier::AsShort:
477 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
481 return ArgType::Invalid();
485 switch (LM.getKind()) {
486 case LengthModifier::AsLongDouble:
488 return Ctx.LongLongTy;
489 case LengthModifier::None:
491 case LengthModifier::AsInt32:
492 return ArgType(Ctx.IntTy, "__int32");
493 case LengthModifier::AsChar: return ArgType::AnyCharTy;
494 case LengthModifier::AsShort: return Ctx.ShortTy;
495 case LengthModifier::AsLong: return Ctx.LongTy;
496 case LengthModifier::AsLongLong:
497 case LengthModifier::AsQuad:
498 return Ctx.LongLongTy;
499 case LengthModifier::AsInt64:
500 return ArgType(Ctx.LongLongTy, "__int64");
501 case LengthModifier::AsIntMax:
502 return ArgType(Ctx.getIntMaxType(), "intmax_t");
503 case LengthModifier::AsSizeT:
504 return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
505 case LengthModifier::AsInt3264:
506 return Ctx.getTargetInfo().getTriple().isArch64Bit()
507 ? ArgType(Ctx.LongLongTy, "__int64")
508 : ArgType(Ctx.IntTy, "__int32");
509 case LengthModifier::AsPtrDiff:
510 return ArgType::makePtrdiffT(
511 ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
512 case LengthModifier::AsAllocate:
513 case LengthModifier::AsMAllocate:
514 case LengthModifier::AsWide:
515 return ArgType::Invalid();
519 switch (LM.getKind()) {
520 case LengthModifier::AsLongDouble:
522 return Ctx.UnsignedLongLongTy;
523 case LengthModifier::None:
524 return Ctx.UnsignedIntTy;
525 case LengthModifier::AsInt32:
526 return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
527 case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
528 case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
529 case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
530 case LengthModifier::AsLongLong:
531 case LengthModifier::AsQuad:
532 return Ctx.UnsignedLongLongTy;
533 case LengthModifier::AsInt64:
534 return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
535 case LengthModifier::AsIntMax:
536 return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
537 case LengthModifier::AsSizeT:
538 return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t"));
539 case LengthModifier::AsInt3264:
540 return Ctx.getTargetInfo().getTriple().isArch64Bit()
541 ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
542 : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
543 case LengthModifier::AsPtrDiff:
544 return ArgType::makePtrdiffT(
545 ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
546 case LengthModifier::AsAllocate:
547 case LengthModifier::AsMAllocate:
548 case LengthModifier::AsWide:
549 return ArgType::Invalid();
552 if (CS.isDoubleArg()) {
553 if (LM.getKind() == LengthModifier::AsLongDouble)
554 return Ctx.LongDoubleTy;
558 if (CS.getKind() == ConversionSpecifier::nArg) {
559 switch (LM.getKind()) {
560 case LengthModifier::None:
561 return ArgType::PtrTo(Ctx.IntTy);
562 case LengthModifier::AsChar:
563 return ArgType::PtrTo(Ctx.SignedCharTy);
564 case LengthModifier::AsShort:
565 return ArgType::PtrTo(Ctx.ShortTy);
566 case LengthModifier::AsLong:
567 return ArgType::PtrTo(Ctx.LongTy);
568 case LengthModifier::AsLongLong:
569 case LengthModifier::AsQuad:
570 return ArgType::PtrTo(Ctx.LongLongTy);
571 case LengthModifier::AsIntMax:
572 return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
573 case LengthModifier::AsSizeT:
574 return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
575 case LengthModifier::AsPtrDiff:
576 return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
577 case LengthModifier::AsLongDouble:
578 return ArgType(); // FIXME: Is this a known extension?
579 case LengthModifier::AsAllocate:
580 case LengthModifier::AsMAllocate:
581 case LengthModifier::AsInt32:
582 case LengthModifier::AsInt3264:
583 case LengthModifier::AsInt64:
584 case LengthModifier::AsWide:
585 return ArgType::Invalid();
589 switch (CS.getKind()) {
590 case ConversionSpecifier::sArg:
591 if (LM.getKind() == LengthModifier::AsWideChar) {
593 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
595 return ArgType(ArgType::WCStrTy, "wchar_t *");
597 if (LM.getKind() == LengthModifier::AsWide)
598 return ArgType(ArgType::WCStrTy, "wchar_t *");
599 return ArgType::CStrTy;
600 case ConversionSpecifier::SArg:
602 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
604 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
605 LM.getKind() == LengthModifier::AsShort)
606 return ArgType::CStrTy;
607 return ArgType(ArgType::WCStrTy, "wchar_t *");
608 case ConversionSpecifier::CArg:
610 return ArgType(Ctx.UnsignedShortTy, "unichar");
611 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
612 LM.getKind() == LengthModifier::AsShort)
614 return ArgType(Ctx.WideCharTy, "wchar_t");
615 case ConversionSpecifier::pArg:
616 case ConversionSpecifier::PArg:
617 return ArgType::CPointerTy;
618 case ConversionSpecifier::ObjCObjArg:
619 return ArgType::ObjCPointerTy;
624 // FIXME: Handle other cases.
629 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
630 bool IsObjCLiteral) const {
631 const PrintfConversionSpecifier &CS = getConversionSpecifier();
633 if (!CS.consumesDataArgument())
634 return ArgType::Invalid();
636 ArgType ScalarTy = getScalarArgType(Ctx, IsObjCLiteral);
637 if (!ScalarTy.isValid() || VectorNumElts.isInvalid())
640 return ScalarTy.makeVectorType(Ctx, VectorNumElts.getConstantAmount());
643 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
644 ASTContext &Ctx, bool IsObjCLiteral) {
645 // %n is different from other conversion specifiers; don't try to fix it.
646 if (CS.getKind() == ConversionSpecifier::nArg)
649 // Handle Objective-C objects first. Note that while the '%@' specifier will
650 // not warn for structure pointer or void pointer arguments (because that's
651 // how CoreFoundation objects are implemented), we only show a fixit for '%@'
652 // if we know it's an object (block, id, class, or __attribute__((NSObject))).
653 if (QT->isObjCRetainableType()) {
657 CS.setKind(ConversionSpecifier::ObjCObjArg);
659 // Disable irrelevant flags
660 HasThousandsGrouping = false;
661 HasPlusPrefix = false;
662 HasSpacePrefix = false;
663 HasAlternativeForm = false;
664 HasLeadingZeroes = false;
665 Precision.setHowSpecified(OptionalAmount::NotSpecified);
666 LM.setKind(LengthModifier::None);
671 // Handle strings next (char *, wchar_t *)
672 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
673 CS.setKind(ConversionSpecifier::sArg);
675 // Disable irrelevant flags
676 HasAlternativeForm = 0;
677 HasLeadingZeroes = 0;
679 // Set the long length modifier for wide characters
680 if (QT->getPointeeType()->isWideCharType())
681 LM.setKind(LengthModifier::AsWideChar);
683 LM.setKind(LengthModifier::None);
688 // If it's an enum, get its underlying type.
689 if (const EnumType *ETy = QT->getAs<EnumType>())
690 QT = ETy->getDecl()->getIntegerType();
692 const BuiltinType *BT = QT->getAs<BuiltinType>();
694 const VectorType *VT = QT->getAs<VectorType>();
696 QT = VT->getElementType();
697 BT = QT->getAs<BuiltinType>();
698 VectorNumElts = OptionalAmount(VT->getNumElements());
702 // We can only work with builtin types.
706 // Set length modifier
707 switch (BT->getKind()) {
708 case BuiltinType::Bool:
709 case BuiltinType::WChar_U:
710 case BuiltinType::WChar_S:
711 case BuiltinType::Char8: // FIXME: Treat like 'char'?
712 case BuiltinType::Char16:
713 case BuiltinType::Char32:
714 case BuiltinType::UInt128:
715 case BuiltinType::Int128:
716 case BuiltinType::Half:
717 case BuiltinType::Float16:
718 case BuiltinType::Float128:
719 case BuiltinType::ShortAccum:
720 case BuiltinType::Accum:
721 case BuiltinType::LongAccum:
722 case BuiltinType::UShortAccum:
723 case BuiltinType::UAccum:
724 case BuiltinType::ULongAccum:
725 case BuiltinType::ShortFract:
726 case BuiltinType::Fract:
727 case BuiltinType::LongFract:
728 case BuiltinType::UShortFract:
729 case BuiltinType::UFract:
730 case BuiltinType::ULongFract:
731 case BuiltinType::SatShortAccum:
732 case BuiltinType::SatAccum:
733 case BuiltinType::SatLongAccum:
734 case BuiltinType::SatUShortAccum:
735 case BuiltinType::SatUAccum:
736 case BuiltinType::SatULongAccum:
737 case BuiltinType::SatShortFract:
738 case BuiltinType::SatFract:
739 case BuiltinType::SatLongFract:
740 case BuiltinType::SatUShortFract:
741 case BuiltinType::SatUFract:
742 case BuiltinType::SatULongFract:
743 // Various types which are non-trivial to correct.
746 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
747 case BuiltinType::Id:
748 #include "clang/Basic/OpenCLImageTypes.def"
749 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
750 case BuiltinType::Id:
751 #include "clang/Basic/OpenCLExtensionTypes.def"
752 #define SIGNED_TYPE(Id, SingletonId)
753 #define UNSIGNED_TYPE(Id, SingletonId)
754 #define FLOATING_TYPE(Id, SingletonId)
755 #define BUILTIN_TYPE(Id, SingletonId) \
756 case BuiltinType::Id:
757 #include "clang/AST/BuiltinTypes.def"
758 // Misc other stuff which doesn't make sense here.
761 case BuiltinType::UInt:
762 case BuiltinType::Int:
763 case BuiltinType::Float:
764 case BuiltinType::Double:
765 LM.setKind(LengthModifier::None);
768 case BuiltinType::Char_U:
769 case BuiltinType::UChar:
770 case BuiltinType::Char_S:
771 case BuiltinType::SChar:
772 LM.setKind(LengthModifier::AsChar);
775 case BuiltinType::Short:
776 case BuiltinType::UShort:
777 LM.setKind(LengthModifier::AsShort);
780 case BuiltinType::Long:
781 case BuiltinType::ULong:
782 LM.setKind(LengthModifier::AsLong);
785 case BuiltinType::LongLong:
786 case BuiltinType::ULongLong:
787 LM.setKind(LengthModifier::AsLongLong);
790 case BuiltinType::LongDouble:
791 LM.setKind(LengthModifier::AsLongDouble);
795 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
796 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
797 namedTypeToLengthModifier(QT, LM);
799 // If fixing the length modifier was enough, we might be done.
800 if (hasValidLengthModifier(Ctx.getTargetInfo())) {
801 // If we're going to offer a fix anyway, make sure the sign matches.
802 switch (CS.getKind()) {
803 case ConversionSpecifier::uArg:
804 case ConversionSpecifier::UArg:
805 if (QT->isSignedIntegerType())
806 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
808 case ConversionSpecifier::dArg:
809 case ConversionSpecifier::DArg:
810 case ConversionSpecifier::iArg:
811 if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
812 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
815 // Other specifiers do not have signed/unsigned variants.
819 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
820 if (ATR.isValid() && ATR.matchesType(Ctx, QT))
824 // Set conversion specifier and disable any flags which do not apply to it.
825 // Let typedefs to char fall through to int, as %c is silly for uint8_t.
826 if (!isa<TypedefType>(QT) && QT->isCharType()) {
827 CS.setKind(ConversionSpecifier::cArg);
828 LM.setKind(LengthModifier::None);
829 Precision.setHowSpecified(OptionalAmount::NotSpecified);
830 HasAlternativeForm = 0;
831 HasLeadingZeroes = 0;
834 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
835 else if (QT->isRealFloatingType()) {
836 CS.setKind(ConversionSpecifier::fArg);
838 else if (QT->isSignedIntegerType()) {
839 CS.setKind(ConversionSpecifier::dArg);
840 HasAlternativeForm = 0;
842 else if (QT->isUnsignedIntegerType()) {
843 CS.setKind(ConversionSpecifier::uArg);
844 HasAlternativeForm = 0;
847 llvm_unreachable("Unexpected type");
853 void PrintfSpecifier::toString(raw_ostream &os) const {
854 // Whilst some features have no defined order, we are using the order
855 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
859 if (usesPositionalArg()) {
860 os << getPositionalArgIndex() << "$";
864 if (IsLeftJustified) os << "-";
865 if (HasPlusPrefix) os << "+";
866 if (HasSpacePrefix) os << " ";
867 if (HasAlternativeForm) os << "#";
868 if (HasLeadingZeroes) os << "0";
870 // Minimum field width
871 FieldWidth.toString(os);
873 Precision.toString(os);
876 if (!VectorNumElts.isInvalid())
877 os << 'v' << VectorNumElts.getConstantAmount();
881 // Conversion specifier
885 bool PrintfSpecifier::hasValidPlusPrefix() const {
889 // The plus prefix only makes sense for signed conversions
890 switch (CS.getKind()) {
891 case ConversionSpecifier::dArg:
892 case ConversionSpecifier::DArg:
893 case ConversionSpecifier::iArg:
894 case ConversionSpecifier::fArg:
895 case ConversionSpecifier::FArg:
896 case ConversionSpecifier::eArg:
897 case ConversionSpecifier::EArg:
898 case ConversionSpecifier::gArg:
899 case ConversionSpecifier::GArg:
900 case ConversionSpecifier::aArg:
901 case ConversionSpecifier::AArg:
902 case ConversionSpecifier::FreeBSDrArg:
903 case ConversionSpecifier::FreeBSDyArg:
911 bool PrintfSpecifier::hasValidAlternativeForm() const {
912 if (!HasAlternativeForm)
915 // Alternate form flag only valid with the oxXaAeEfFgG conversions
916 switch (CS.getKind()) {
917 case ConversionSpecifier::oArg:
918 case ConversionSpecifier::OArg:
919 case ConversionSpecifier::xArg:
920 case ConversionSpecifier::XArg:
921 case ConversionSpecifier::aArg:
922 case ConversionSpecifier::AArg:
923 case ConversionSpecifier::eArg:
924 case ConversionSpecifier::EArg:
925 case ConversionSpecifier::fArg:
926 case ConversionSpecifier::FArg:
927 case ConversionSpecifier::gArg:
928 case ConversionSpecifier::GArg:
929 case ConversionSpecifier::FreeBSDrArg:
930 case ConversionSpecifier::FreeBSDyArg:
938 bool PrintfSpecifier::hasValidLeadingZeros() const {
939 if (!HasLeadingZeroes)
942 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
943 switch (CS.getKind()) {
944 case ConversionSpecifier::dArg:
945 case ConversionSpecifier::DArg:
946 case ConversionSpecifier::iArg:
947 case ConversionSpecifier::oArg:
948 case ConversionSpecifier::OArg:
949 case ConversionSpecifier::uArg:
950 case ConversionSpecifier::UArg:
951 case ConversionSpecifier::xArg:
952 case ConversionSpecifier::XArg:
953 case ConversionSpecifier::aArg:
954 case ConversionSpecifier::AArg:
955 case ConversionSpecifier::eArg:
956 case ConversionSpecifier::EArg:
957 case ConversionSpecifier::fArg:
958 case ConversionSpecifier::FArg:
959 case ConversionSpecifier::gArg:
960 case ConversionSpecifier::GArg:
961 case ConversionSpecifier::FreeBSDrArg:
962 case ConversionSpecifier::FreeBSDyArg:
970 bool PrintfSpecifier::hasValidSpacePrefix() const {
974 // The space prefix only makes sense for signed conversions
975 switch (CS.getKind()) {
976 case ConversionSpecifier::dArg:
977 case ConversionSpecifier::DArg:
978 case ConversionSpecifier::iArg:
979 case ConversionSpecifier::fArg:
980 case ConversionSpecifier::FArg:
981 case ConversionSpecifier::eArg:
982 case ConversionSpecifier::EArg:
983 case ConversionSpecifier::gArg:
984 case ConversionSpecifier::GArg:
985 case ConversionSpecifier::aArg:
986 case ConversionSpecifier::AArg:
987 case ConversionSpecifier::FreeBSDrArg:
988 case ConversionSpecifier::FreeBSDyArg:
996 bool PrintfSpecifier::hasValidLeftJustified() const {
997 if (!IsLeftJustified)
1000 // The left justified flag is valid for all conversions except n
1001 switch (CS.getKind()) {
1002 case ConversionSpecifier::nArg:
1010 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
1011 if (!HasThousandsGrouping)
1014 switch (CS.getKind()) {
1015 case ConversionSpecifier::dArg:
1016 case ConversionSpecifier::DArg:
1017 case ConversionSpecifier::iArg:
1018 case ConversionSpecifier::uArg:
1019 case ConversionSpecifier::UArg:
1020 case ConversionSpecifier::fArg:
1021 case ConversionSpecifier::FArg:
1022 case ConversionSpecifier::gArg:
1023 case ConversionSpecifier::GArg:
1030 bool PrintfSpecifier::hasValidPrecision() const {
1031 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
1034 // Precision is only valid with the diouxXaAeEfFgGsP conversions
1035 switch (CS.getKind()) {
1036 case ConversionSpecifier::dArg:
1037 case ConversionSpecifier::DArg:
1038 case ConversionSpecifier::iArg:
1039 case ConversionSpecifier::oArg:
1040 case ConversionSpecifier::OArg:
1041 case ConversionSpecifier::uArg:
1042 case ConversionSpecifier::UArg:
1043 case ConversionSpecifier::xArg:
1044 case ConversionSpecifier::XArg:
1045 case ConversionSpecifier::aArg:
1046 case ConversionSpecifier::AArg:
1047 case ConversionSpecifier::eArg:
1048 case ConversionSpecifier::EArg:
1049 case ConversionSpecifier::fArg:
1050 case ConversionSpecifier::FArg:
1051 case ConversionSpecifier::gArg:
1052 case ConversionSpecifier::GArg:
1053 case ConversionSpecifier::sArg:
1054 case ConversionSpecifier::FreeBSDrArg:
1055 case ConversionSpecifier::FreeBSDyArg:
1056 case ConversionSpecifier::PArg:
1063 bool PrintfSpecifier::hasValidFieldWidth() const {
1064 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
1067 // The field width is valid for all conversions except n
1068 switch (CS.getKind()) {
1069 case ConversionSpecifier::nArg: