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