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" 15 #include "clang/Basic/LangOptions.h" 16 #include "clang/Basic/TargetInfo.h" 17 #include "llvm/Support/ConvertUTF.h" 18 19 using clang::analyze_format_string::ArgType; 20 using clang::analyze_format_string::FormatStringHandler; 21 using clang::analyze_format_string::FormatSpecifier; 22 using clang::analyze_format_string::LengthModifier; 23 using clang::analyze_format_string::OptionalAmount; 24 using clang::analyze_format_string::PositionContext; 25 using clang::analyze_format_string::ConversionSpecifier; 26 using namespace clang; 27 28 // Key function to FormatStringHandler. 29 FormatStringHandler::~FormatStringHandler() {} 30 31 //===----------------------------------------------------------------------===// 32 // Functions for parsing format strings components in both printf and 33 // scanf format strings. 34 //===----------------------------------------------------------------------===// 35 36 OptionalAmount 37 clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) { 38 const char *I = Beg; 39 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 40 41 unsigned accumulator = 0; 42 bool hasDigits = false; 43 44 for ( ; I != E; ++I) { 45 char c = *I; 46 if (c >= '0' && c <= '9') { 47 hasDigits = true; 48 accumulator = (accumulator * 10) + (c - '0'); 49 continue; 50 } 51 52 if (hasDigits) 53 return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg, 54 false); 55 56 break; 57 } 58 59 return OptionalAmount(); 60 } 61 62 OptionalAmount 63 clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg, 64 const char *E, 65 unsigned &argIndex) { 66 if (*Beg == '*') { 67 ++Beg; 68 return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false); 69 } 70 71 return ParseAmount(Beg, E); 72 } 73 74 OptionalAmount 75 clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H, 76 const char *Start, 77 const char *&Beg, 78 const char *E, 79 PositionContext p) { 80 if (*Beg == '*') { 81 const char *I = Beg + 1; 82 const OptionalAmount &Amt = ParseAmount(I, E); 83 84 if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) { 85 H.HandleInvalidPosition(Beg, I - Beg, p); 86 return OptionalAmount(false); 87 } 88 89 if (I == E) { 90 // No more characters left? 91 H.HandleIncompleteSpecifier(Start, E - Start); 92 return OptionalAmount(false); 93 } 94 95 assert(Amt.getHowSpecified() == OptionalAmount::Constant); 96 97 if (*I == '$') { 98 // Handle positional arguments 99 100 // Special case: '*0$', since this is an easy mistake. 101 if (Amt.getConstantAmount() == 0) { 102 H.HandleZeroPosition(Beg, I - Beg + 1); 103 return OptionalAmount(false); 104 } 105 106 const char *Tmp = Beg; 107 Beg = ++I; 108 109 return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1, 110 Tmp, 0, true); 111 } 112 113 H.HandleInvalidPosition(Beg, I - Beg, p); 114 return OptionalAmount(false); 115 } 116 117 return ParseAmount(Beg, E); 118 } 119 120 121 bool 122 clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H, 123 FormatSpecifier &CS, 124 const char *Start, 125 const char *&Beg, const char *E, 126 unsigned *argIndex) { 127 // FIXME: Support negative field widths. 128 if (argIndex) { 129 CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex)); 130 } 131 else { 132 const OptionalAmount Amt = 133 ParsePositionAmount(H, Start, Beg, E, 134 analyze_format_string::FieldWidthPos); 135 136 if (Amt.isInvalid()) 137 return true; 138 CS.setFieldWidth(Amt); 139 } 140 return false; 141 } 142 143 bool 144 clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H, 145 FormatSpecifier &FS, 146 const char *Start, 147 const char *&Beg, 148 const char *E) { 149 const char *I = Beg; 150 151 const OptionalAmount &Amt = ParseAmount(I, E); 152 153 if (I == E) { 154 // No more characters left? 155 H.HandleIncompleteSpecifier(Start, E - Start); 156 return true; 157 } 158 159 if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') { 160 // Warn that positional arguments are non-standard. 161 H.HandlePosition(Start, I - Start); 162 163 // Special case: '%0$', since this is an easy mistake. 164 if (Amt.getConstantAmount() == 0) { 165 H.HandleZeroPosition(Start, I - Start); 166 return true; 167 } 168 169 FS.setArgIndex(Amt.getConstantAmount() - 1); 170 FS.setUsesPositionalArg(); 171 // Update the caller's pointer if we decided to consume 172 // these characters. 173 Beg = I; 174 return false; 175 } 176 177 return false; 178 } 179 180 bool 181 clang::analyze_format_string::ParseVectorModifier(FormatStringHandler &H, 182 FormatSpecifier &FS, 183 const char *&I, 184 const char *E, 185 const LangOptions &LO) { 186 if (!LO.OpenCL) 187 return false; 188 189 const char *Start = I; 190 if (*I == 'v') { 191 ++I; 192 193 if (I == E) { 194 H.HandleIncompleteSpecifier(Start, E - Start); 195 return true; 196 } 197 198 OptionalAmount NumElts = ParseAmount(I, E); 199 if (NumElts.getHowSpecified() != OptionalAmount::Constant) { 200 H.HandleIncompleteSpecifier(Start, E - Start); 201 return true; 202 } 203 204 FS.setVectorNumElts(NumElts); 205 } 206 207 return false; 208 } 209 210 bool 211 clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS, 212 const char *&I, 213 const char *E, 214 const LangOptions &LO, 215 bool IsScanf) { 216 LengthModifier::Kind lmKind = LengthModifier::None; 217 const char *lmPosition = I; 218 switch (*I) { 219 default: 220 return false; 221 case 'h': 222 ++I; 223 if (I != E && *I == 'h') { 224 ++I; 225 lmKind = LengthModifier::AsChar; 226 } else { 227 lmKind = LengthModifier::AsShort; 228 } 229 break; 230 case 'l': 231 ++I; 232 if (I != E && *I == 'l') { 233 ++I; 234 lmKind = LengthModifier::AsLongLong; 235 } else { 236 lmKind = LengthModifier::AsLong; 237 } 238 break; 239 case 'j': lmKind = LengthModifier::AsIntMax; ++I; break; 240 case 'z': lmKind = LengthModifier::AsSizeT; ++I; break; 241 case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break; 242 case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break; 243 case 'q': lmKind = LengthModifier::AsQuad; ++I; break; 244 case 'a': 245 if (IsScanf && !LO.C99 && !LO.CPlusPlus11) { 246 // For scanf in C90, look at the next character to see if this should 247 // be parsed as the GNU extension 'a' length modifier. If not, this 248 // will be parsed as a conversion specifier. 249 ++I; 250 if (I != E && (*I == 's' || *I == 'S' || *I == '[')) { 251 lmKind = LengthModifier::AsAllocate; 252 break; 253 } 254 --I; 255 } 256 return false; 257 case 'm': 258 if (IsScanf) { 259 lmKind = LengthModifier::AsMAllocate; 260 ++I; 261 break; 262 } 263 return false; 264 // printf: AsInt64, AsInt32, AsInt3264 265 // scanf: AsInt64 266 case 'I': 267 if (I + 1 != E && I + 2 != E) { 268 if (I[1] == '6' && I[2] == '4') { 269 I += 3; 270 lmKind = LengthModifier::AsInt64; 271 break; 272 } 273 if (IsScanf) 274 return false; 275 276 if (I[1] == '3' && I[2] == '2') { 277 I += 3; 278 lmKind = LengthModifier::AsInt32; 279 break; 280 } 281 } 282 ++I; 283 lmKind = LengthModifier::AsInt3264; 284 break; 285 case 'w': 286 lmKind = LengthModifier::AsWide; ++I; break; 287 } 288 LengthModifier lm(lmPosition, lmKind); 289 FS.setLengthModifier(lm); 290 return true; 291 } 292 293 bool clang::analyze_format_string::ParseUTF8InvalidSpecifier( 294 const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) { 295 if (SpecifierBegin + 1 >= FmtStrEnd) 296 return false; 297 298 const llvm::UTF8 *SB = 299 reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1); 300 const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd); 301 const char FirstByte = *SB; 302 303 // If the invalid specifier is a multibyte UTF-8 string, return the 304 // total length accordingly so that the conversion specifier can be 305 // properly updated to reflect a complete UTF-8 specifier. 306 unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte); 307 if (NumBytes == 1) 308 return false; 309 if (SB + NumBytes > SE) 310 return false; 311 312 Len = NumBytes + 1; 313 return true; 314 } 315 316 //===----------------------------------------------------------------------===// 317 // Methods on ArgType. 318 //===----------------------------------------------------------------------===// 319 320 clang::analyze_format_string::ArgType::MatchKind 321 ArgType::matchesType(ASTContext &C, QualType argTy) const { 322 if (Ptr) { 323 // It has to be a pointer. 324 const PointerType *PT = argTy->getAs<PointerType>(); 325 if (!PT) 326 return NoMatch; 327 328 // We cannot write through a const qualified pointer. 329 if (PT->getPointeeType().isConstQualified()) 330 return NoMatch; 331 332 argTy = PT->getPointeeType(); 333 } 334 335 switch (K) { 336 case InvalidTy: 337 llvm_unreachable("ArgType must be valid"); 338 339 case UnknownTy: 340 return Match; 341 342 case AnyCharTy: { 343 if (const EnumType *ETy = argTy->getAs<EnumType>()) { 344 // If the enum is incomplete we know nothing about the underlying type. 345 // Assume that it's 'int'. 346 if (!ETy->getDecl()->isComplete()) 347 return NoMatch; 348 argTy = ETy->getDecl()->getIntegerType(); 349 } 350 351 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 352 switch (BT->getKind()) { 353 default: 354 break; 355 case BuiltinType::Char_S: 356 case BuiltinType::SChar: 357 case BuiltinType::UChar: 358 case BuiltinType::Char_U: 359 return Match; 360 } 361 return NoMatch; 362 } 363 364 case SpecificTy: { 365 if (const EnumType *ETy = argTy->getAs<EnumType>()) { 366 // If the enum is incomplete we know nothing about the underlying type. 367 // Assume that it's 'int'. 368 if (!ETy->getDecl()->isComplete()) 369 argTy = C.IntTy; 370 else 371 argTy = ETy->getDecl()->getIntegerType(); 372 } 373 argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 374 375 if (T == argTy) 376 return Match; 377 // Check for "compatible types". 378 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 379 switch (BT->getKind()) { 380 default: 381 break; 382 case BuiltinType::Char_S: 383 case BuiltinType::SChar: 384 case BuiltinType::Char_U: 385 case BuiltinType::UChar: 386 return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match 387 : NoMatch; 388 case BuiltinType::Short: 389 return T == C.UnsignedShortTy ? Match : NoMatch; 390 case BuiltinType::UShort: 391 return T == C.ShortTy ? Match : NoMatch; 392 case BuiltinType::Int: 393 return T == C.UnsignedIntTy ? Match : NoMatch; 394 case BuiltinType::UInt: 395 return T == C.IntTy ? Match : NoMatch; 396 case BuiltinType::Long: 397 return T == C.UnsignedLongTy ? Match : NoMatch; 398 case BuiltinType::ULong: 399 return T == C.LongTy ? Match : NoMatch; 400 case BuiltinType::LongLong: 401 return T == C.UnsignedLongLongTy ? Match : NoMatch; 402 case BuiltinType::ULongLong: 403 return T == C.LongLongTy ? Match : NoMatch; 404 } 405 return NoMatch; 406 } 407 408 case CStrTy: { 409 const PointerType *PT = argTy->getAs<PointerType>(); 410 if (!PT) 411 return NoMatch; 412 QualType pointeeTy = PT->getPointeeType(); 413 if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 414 switch (BT->getKind()) { 415 case BuiltinType::Void: 416 case BuiltinType::Char_U: 417 case BuiltinType::UChar: 418 case BuiltinType::Char_S: 419 case BuiltinType::SChar: 420 return Match; 421 default: 422 break; 423 } 424 425 return NoMatch; 426 } 427 428 case WCStrTy: { 429 const PointerType *PT = argTy->getAs<PointerType>(); 430 if (!PT) 431 return NoMatch; 432 QualType pointeeTy = 433 C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 434 return pointeeTy == C.getWideCharType() ? Match : NoMatch; 435 } 436 437 case WIntTy: { 438 QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); 439 440 if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt) 441 return Match; 442 443 QualType PromoArg = argTy->isPromotableIntegerType() 444 ? C.getPromotedIntegerType(argTy) 445 : argTy; 446 PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); 447 448 // If the promoted argument is the corresponding signed type of the 449 // wint_t type, then it should match. 450 if (PromoArg->hasSignedIntegerRepresentation() && 451 C.getCorrespondingUnsignedType(PromoArg) == WInt) 452 return Match; 453 454 return WInt == PromoArg ? Match : NoMatch; 455 } 456 457 case CPointerTy: 458 if (argTy->isVoidPointerType()) { 459 return Match; 460 } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() || 461 argTy->isBlockPointerType() || argTy->isNullPtrType()) { 462 return NoMatchPedantic; 463 } else { 464 return NoMatch; 465 } 466 467 case ObjCPointerTy: { 468 if (argTy->getAs<ObjCObjectPointerType>() || 469 argTy->getAs<BlockPointerType>()) 470 return Match; 471 472 // Handle implicit toll-free bridging. 473 if (const PointerType *PT = argTy->getAs<PointerType>()) { 474 // Things such as CFTypeRef are really just opaque pointers 475 // to C structs representing CF types that can often be bridged 476 // to Objective-C objects. Since the compiler doesn't know which 477 // structs can be toll-free bridged, we just accept them all. 478 QualType pointee = PT->getPointeeType(); 479 if (pointee->getAsStructureType() || pointee->isVoidType()) 480 return Match; 481 } 482 return NoMatch; 483 } 484 } 485 486 llvm_unreachable("Invalid ArgType Kind!"); 487 } 488 489 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const { 490 if (K != SpecificTy) // Won't be a valid vector element type. 491 return ArgType::Invalid(); 492 493 QualType Vec = C.getExtVectorType(T, NumElts); 494 return ArgType(Vec, Name); 495 } 496 497 QualType ArgType::getRepresentativeType(ASTContext &C) const { 498 QualType Res; 499 switch (K) { 500 case InvalidTy: 501 llvm_unreachable("No representative type for Invalid ArgType"); 502 case UnknownTy: 503 llvm_unreachable("No representative type for Unknown ArgType"); 504 case AnyCharTy: 505 Res = C.CharTy; 506 break; 507 case SpecificTy: 508 Res = T; 509 break; 510 case CStrTy: 511 Res = C.getPointerType(C.CharTy); 512 break; 513 case WCStrTy: 514 Res = C.getPointerType(C.getWideCharType()); 515 break; 516 case ObjCPointerTy: 517 Res = C.ObjCBuiltinIdTy; 518 break; 519 case CPointerTy: 520 Res = C.VoidPtrTy; 521 break; 522 case WIntTy: { 523 Res = C.getWIntType(); 524 break; 525 } 526 } 527 528 if (Ptr) 529 Res = C.getPointerType(Res); 530 return Res; 531 } 532 533 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const { 534 std::string S = getRepresentativeType(C).getAsString(); 535 536 std::string Alias; 537 if (Name) { 538 // Use a specific name for this type, e.g. "size_t". 539 Alias = Name; 540 if (Ptr) { 541 // If ArgType is actually a pointer to T, append an asterisk. 542 Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *"; 543 } 544 // If Alias is the same as the underlying type, e.g. wchar_t, then drop it. 545 if (S == Alias) 546 Alias.clear(); 547 } 548 549 if (!Alias.empty()) 550 return std::string("'") + Alias + "' (aka '" + S + "')"; 551 return std::string("'") + S + "'"; 552 } 553 554 555 //===----------------------------------------------------------------------===// 556 // Methods on OptionalAmount. 557 //===----------------------------------------------------------------------===// 558 559 ArgType 560 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { 561 return Ctx.IntTy; 562 } 563 564 //===----------------------------------------------------------------------===// 565 // Methods on LengthModifier. 566 //===----------------------------------------------------------------------===// 567 568 const char * 569 analyze_format_string::LengthModifier::toString() const { 570 switch (kind) { 571 case AsChar: 572 return "hh"; 573 case AsShort: 574 return "h"; 575 case AsLong: // or AsWideChar 576 return "l"; 577 case AsLongLong: 578 return "ll"; 579 case AsQuad: 580 return "q"; 581 case AsIntMax: 582 return "j"; 583 case AsSizeT: 584 return "z"; 585 case AsPtrDiff: 586 return "t"; 587 case AsInt32: 588 return "I32"; 589 case AsInt3264: 590 return "I"; 591 case AsInt64: 592 return "I64"; 593 case AsLongDouble: 594 return "L"; 595 case AsAllocate: 596 return "a"; 597 case AsMAllocate: 598 return "m"; 599 case AsWide: 600 return "w"; 601 case None: 602 return ""; 603 } 604 return nullptr; 605 } 606 607 //===----------------------------------------------------------------------===// 608 // Methods on ConversionSpecifier. 609 //===----------------------------------------------------------------------===// 610 611 const char *ConversionSpecifier::toString() const { 612 switch (kind) { 613 case dArg: return "d"; 614 case DArg: return "D"; 615 case iArg: return "i"; 616 case oArg: return "o"; 617 case OArg: return "O"; 618 case uArg: return "u"; 619 case UArg: return "U"; 620 case xArg: return "x"; 621 case XArg: return "X"; 622 case fArg: return "f"; 623 case FArg: return "F"; 624 case eArg: return "e"; 625 case EArg: return "E"; 626 case gArg: return "g"; 627 case GArg: return "G"; 628 case aArg: return "a"; 629 case AArg: return "A"; 630 case cArg: return "c"; 631 case sArg: return "s"; 632 case pArg: return "p"; 633 case PArg: 634 return "P"; 635 case nArg: return "n"; 636 case PercentArg: return "%"; 637 case ScanListArg: return "["; 638 case InvalidSpecifier: return nullptr; 639 640 // POSIX unicode extensions. 641 case CArg: return "C"; 642 case SArg: return "S"; 643 644 // Objective-C specific specifiers. 645 case ObjCObjArg: return "@"; 646 647 // FreeBSD kernel specific specifiers. 648 case FreeBSDbArg: return "b"; 649 case FreeBSDDArg: return "D"; 650 case FreeBSDrArg: return "r"; 651 case FreeBSDyArg: return "y"; 652 653 // GlibC specific specifiers. 654 case PrintErrno: return "m"; 655 656 // MS specific specifiers. 657 case ZArg: return "Z"; 658 } 659 return nullptr; 660 } 661 662 Optional<ConversionSpecifier> 663 ConversionSpecifier::getStandardSpecifier() const { 664 ConversionSpecifier::Kind NewKind; 665 666 switch (getKind()) { 667 default: 668 return None; 669 case DArg: 670 NewKind = dArg; 671 break; 672 case UArg: 673 NewKind = uArg; 674 break; 675 case OArg: 676 NewKind = oArg; 677 break; 678 } 679 680 ConversionSpecifier FixedCS(*this); 681 FixedCS.setKind(NewKind); 682 return FixedCS; 683 } 684 685 //===----------------------------------------------------------------------===// 686 // Methods on OptionalAmount. 687 //===----------------------------------------------------------------------===// 688 689 void OptionalAmount::toString(raw_ostream &os) const { 690 switch (hs) { 691 case Invalid: 692 case NotSpecified: 693 return; 694 case Arg: 695 if (UsesDotPrefix) 696 os << "."; 697 if (usesPositionalArg()) 698 os << "*" << getPositionalArgIndex() << "$"; 699 else 700 os << "*"; 701 break; 702 case Constant: 703 if (UsesDotPrefix) 704 os << "."; 705 os << amt; 706 break; 707 } 708 } 709 710 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { 711 switch (LM.getKind()) { 712 case LengthModifier::None: 713 return true; 714 715 // Handle most integer flags 716 case LengthModifier::AsShort: 717 if (Target.getTriple().isOSMSVCRT()) { 718 switch (CS.getKind()) { 719 case ConversionSpecifier::cArg: 720 case ConversionSpecifier::CArg: 721 case ConversionSpecifier::sArg: 722 case ConversionSpecifier::SArg: 723 case ConversionSpecifier::ZArg: 724 return true; 725 default: 726 break; 727 } 728 } 729 LLVM_FALLTHROUGH; 730 case LengthModifier::AsChar: 731 case LengthModifier::AsLongLong: 732 case LengthModifier::AsQuad: 733 case LengthModifier::AsIntMax: 734 case LengthModifier::AsSizeT: 735 case LengthModifier::AsPtrDiff: 736 switch (CS.getKind()) { 737 case ConversionSpecifier::dArg: 738 case ConversionSpecifier::DArg: 739 case ConversionSpecifier::iArg: 740 case ConversionSpecifier::oArg: 741 case ConversionSpecifier::OArg: 742 case ConversionSpecifier::uArg: 743 case ConversionSpecifier::UArg: 744 case ConversionSpecifier::xArg: 745 case ConversionSpecifier::XArg: 746 case ConversionSpecifier::nArg: 747 return true; 748 case ConversionSpecifier::FreeBSDrArg: 749 case ConversionSpecifier::FreeBSDyArg: 750 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 751 default: 752 return false; 753 } 754 755 // Handle 'l' flag 756 case LengthModifier::AsLong: // or AsWideChar 757 switch (CS.getKind()) { 758 case ConversionSpecifier::dArg: 759 case ConversionSpecifier::DArg: 760 case ConversionSpecifier::iArg: 761 case ConversionSpecifier::oArg: 762 case ConversionSpecifier::OArg: 763 case ConversionSpecifier::uArg: 764 case ConversionSpecifier::UArg: 765 case ConversionSpecifier::xArg: 766 case ConversionSpecifier::XArg: 767 case ConversionSpecifier::aArg: 768 case ConversionSpecifier::AArg: 769 case ConversionSpecifier::fArg: 770 case ConversionSpecifier::FArg: 771 case ConversionSpecifier::eArg: 772 case ConversionSpecifier::EArg: 773 case ConversionSpecifier::gArg: 774 case ConversionSpecifier::GArg: 775 case ConversionSpecifier::nArg: 776 case ConversionSpecifier::cArg: 777 case ConversionSpecifier::sArg: 778 case ConversionSpecifier::ScanListArg: 779 case ConversionSpecifier::ZArg: 780 return true; 781 case ConversionSpecifier::FreeBSDrArg: 782 case ConversionSpecifier::FreeBSDyArg: 783 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 784 default: 785 return false; 786 } 787 788 case LengthModifier::AsLongDouble: 789 switch (CS.getKind()) { 790 case ConversionSpecifier::aArg: 791 case ConversionSpecifier::AArg: 792 case ConversionSpecifier::fArg: 793 case ConversionSpecifier::FArg: 794 case ConversionSpecifier::eArg: 795 case ConversionSpecifier::EArg: 796 case ConversionSpecifier::gArg: 797 case ConversionSpecifier::GArg: 798 return true; 799 // GNU libc extension. 800 case ConversionSpecifier::dArg: 801 case ConversionSpecifier::iArg: 802 case ConversionSpecifier::oArg: 803 case ConversionSpecifier::uArg: 804 case ConversionSpecifier::xArg: 805 case ConversionSpecifier::XArg: 806 return !Target.getTriple().isOSDarwin() && 807 !Target.getTriple().isOSWindows(); 808 default: 809 return false; 810 } 811 812 case LengthModifier::AsAllocate: 813 switch (CS.getKind()) { 814 case ConversionSpecifier::sArg: 815 case ConversionSpecifier::SArg: 816 case ConversionSpecifier::ScanListArg: 817 return true; 818 default: 819 return false; 820 } 821 822 case LengthModifier::AsMAllocate: 823 switch (CS.getKind()) { 824 case ConversionSpecifier::cArg: 825 case ConversionSpecifier::CArg: 826 case ConversionSpecifier::sArg: 827 case ConversionSpecifier::SArg: 828 case ConversionSpecifier::ScanListArg: 829 return true; 830 default: 831 return false; 832 } 833 case LengthModifier::AsInt32: 834 case LengthModifier::AsInt3264: 835 case LengthModifier::AsInt64: 836 switch (CS.getKind()) { 837 case ConversionSpecifier::dArg: 838 case ConversionSpecifier::iArg: 839 case ConversionSpecifier::oArg: 840 case ConversionSpecifier::uArg: 841 case ConversionSpecifier::xArg: 842 case ConversionSpecifier::XArg: 843 return Target.getTriple().isOSMSVCRT(); 844 default: 845 return false; 846 } 847 case LengthModifier::AsWide: 848 switch (CS.getKind()) { 849 case ConversionSpecifier::cArg: 850 case ConversionSpecifier::CArg: 851 case ConversionSpecifier::sArg: 852 case ConversionSpecifier::SArg: 853 case ConversionSpecifier::ZArg: 854 return Target.getTriple().isOSMSVCRT(); 855 default: 856 return false; 857 } 858 } 859 llvm_unreachable("Invalid LengthModifier Kind!"); 860 } 861 862 bool FormatSpecifier::hasStandardLengthModifier() const { 863 switch (LM.getKind()) { 864 case LengthModifier::None: 865 case LengthModifier::AsChar: 866 case LengthModifier::AsShort: 867 case LengthModifier::AsLong: 868 case LengthModifier::AsLongLong: 869 case LengthModifier::AsIntMax: 870 case LengthModifier::AsSizeT: 871 case LengthModifier::AsPtrDiff: 872 case LengthModifier::AsLongDouble: 873 return true; 874 case LengthModifier::AsAllocate: 875 case LengthModifier::AsMAllocate: 876 case LengthModifier::AsQuad: 877 case LengthModifier::AsInt32: 878 case LengthModifier::AsInt3264: 879 case LengthModifier::AsInt64: 880 case LengthModifier::AsWide: 881 return false; 882 } 883 llvm_unreachable("Invalid LengthModifier Kind!"); 884 } 885 886 bool FormatSpecifier::hasStandardConversionSpecifier( 887 const LangOptions &LangOpt) const { 888 switch (CS.getKind()) { 889 case ConversionSpecifier::cArg: 890 case ConversionSpecifier::dArg: 891 case ConversionSpecifier::iArg: 892 case ConversionSpecifier::oArg: 893 case ConversionSpecifier::uArg: 894 case ConversionSpecifier::xArg: 895 case ConversionSpecifier::XArg: 896 case ConversionSpecifier::fArg: 897 case ConversionSpecifier::FArg: 898 case ConversionSpecifier::eArg: 899 case ConversionSpecifier::EArg: 900 case ConversionSpecifier::gArg: 901 case ConversionSpecifier::GArg: 902 case ConversionSpecifier::aArg: 903 case ConversionSpecifier::AArg: 904 case ConversionSpecifier::sArg: 905 case ConversionSpecifier::pArg: 906 case ConversionSpecifier::nArg: 907 case ConversionSpecifier::ObjCObjArg: 908 case ConversionSpecifier::ScanListArg: 909 case ConversionSpecifier::PercentArg: 910 case ConversionSpecifier::PArg: 911 return true; 912 case ConversionSpecifier::CArg: 913 case ConversionSpecifier::SArg: 914 return LangOpt.ObjC; 915 case ConversionSpecifier::InvalidSpecifier: 916 case ConversionSpecifier::FreeBSDbArg: 917 case ConversionSpecifier::FreeBSDDArg: 918 case ConversionSpecifier::FreeBSDrArg: 919 case ConversionSpecifier::FreeBSDyArg: 920 case ConversionSpecifier::PrintErrno: 921 case ConversionSpecifier::DArg: 922 case ConversionSpecifier::OArg: 923 case ConversionSpecifier::UArg: 924 case ConversionSpecifier::ZArg: 925 return false; 926 } 927 llvm_unreachable("Invalid ConversionSpecifier Kind!"); 928 } 929 930 bool FormatSpecifier::hasStandardLengthConversionCombination() const { 931 if (LM.getKind() == LengthModifier::AsLongDouble) { 932 switch(CS.getKind()) { 933 case ConversionSpecifier::dArg: 934 case ConversionSpecifier::iArg: 935 case ConversionSpecifier::oArg: 936 case ConversionSpecifier::uArg: 937 case ConversionSpecifier::xArg: 938 case ConversionSpecifier::XArg: 939 return false; 940 default: 941 return true; 942 } 943 } 944 return true; 945 } 946 947 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { 948 if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { 949 if (LM.getKind() == LengthModifier::AsLongDouble || 950 LM.getKind() == LengthModifier::AsQuad) { 951 LengthModifier FixedLM(LM); 952 FixedLM.setKind(LengthModifier::AsLongLong); 953 return FixedLM; 954 } 955 } 956 957 return None; 958 } 959 960 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 961 LengthModifier &LM) { 962 assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 963 const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 964 965 for (;;) { 966 const IdentifierInfo *Identifier = Typedef->getIdentifier(); 967 if (Identifier->getName() == "size_t") { 968 LM.setKind(LengthModifier::AsSizeT); 969 return true; 970 } else if (Identifier->getName() == "ssize_t") { 971 // Not C99, but common in Unix. 972 LM.setKind(LengthModifier::AsSizeT); 973 return true; 974 } else if (Identifier->getName() == "intmax_t") { 975 LM.setKind(LengthModifier::AsIntMax); 976 return true; 977 } else if (Identifier->getName() == "uintmax_t") { 978 LM.setKind(LengthModifier::AsIntMax); 979 return true; 980 } else if (Identifier->getName() == "ptrdiff_t") { 981 LM.setKind(LengthModifier::AsPtrDiff); 982 return true; 983 } 984 985 QualType T = Typedef->getUnderlyingType(); 986 if (!isa<TypedefType>(T)) 987 break; 988 989 Typedef = cast<TypedefType>(T)->getDecl(); 990 } 991 return false; 992 } 993