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 llvm::UTF8 *SB = 270 reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1); 271 const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd); 272 const char FirstByte = *SB; 273 274 // If the invalid specifier is a multibyte UTF-8 string, return the 275 // total length accordingly so that the conversion specifier can be 276 // properly updated to reflect a complete UTF-8 specifier. 277 unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte); 278 if (NumBytes == 1) 279 return false; 280 if (SB + NumBytes > SE) 281 return false; 282 283 Len = NumBytes + 1; 284 return true; 285 } 286 287 //===----------------------------------------------------------------------===// 288 // Methods on ArgType. 289 //===----------------------------------------------------------------------===// 290 291 clang::analyze_format_string::ArgType::MatchKind 292 ArgType::matchesType(ASTContext &C, QualType argTy) const { 293 if (Ptr) { 294 // It has to be a pointer. 295 const PointerType *PT = argTy->getAs<PointerType>(); 296 if (!PT) 297 return NoMatch; 298 299 // We cannot write through a const qualified pointer. 300 if (PT->getPointeeType().isConstQualified()) 301 return NoMatch; 302 303 argTy = PT->getPointeeType(); 304 } 305 306 switch (K) { 307 case InvalidTy: 308 llvm_unreachable("ArgType must be valid"); 309 310 case UnknownTy: 311 return Match; 312 313 case AnyCharTy: { 314 if (const EnumType *ETy = argTy->getAs<EnumType>()) { 315 // If the enum is incomplete we know nothing about the underlying type. 316 // Assume that it's 'int'. 317 if (!ETy->getDecl()->isComplete()) 318 return NoMatch; 319 argTy = ETy->getDecl()->getIntegerType(); 320 } 321 322 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 323 switch (BT->getKind()) { 324 default: 325 break; 326 case BuiltinType::Char_S: 327 case BuiltinType::SChar: 328 case BuiltinType::UChar: 329 case BuiltinType::Char_U: 330 return Match; 331 } 332 return NoMatch; 333 } 334 335 case SpecificTy: { 336 if (const EnumType *ETy = argTy->getAs<EnumType>()) { 337 // If the enum is incomplete we know nothing about the underlying type. 338 // Assume that it's 'int'. 339 if (!ETy->getDecl()->isComplete()) 340 argTy = C.IntTy; 341 else 342 argTy = ETy->getDecl()->getIntegerType(); 343 } 344 argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 345 346 if (T == argTy) 347 return Match; 348 // Check for "compatible types". 349 if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 350 switch (BT->getKind()) { 351 default: 352 break; 353 case BuiltinType::Char_S: 354 case BuiltinType::SChar: 355 case BuiltinType::Char_U: 356 case BuiltinType::UChar: 357 return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match 358 : NoMatch; 359 case BuiltinType::Short: 360 return T == C.UnsignedShortTy ? Match : NoMatch; 361 case BuiltinType::UShort: 362 return T == C.ShortTy ? Match : NoMatch; 363 case BuiltinType::Int: 364 return T == C.UnsignedIntTy ? Match : NoMatch; 365 case BuiltinType::UInt: 366 return T == C.IntTy ? Match : NoMatch; 367 case BuiltinType::Long: 368 return T == C.UnsignedLongTy ? Match : NoMatch; 369 case BuiltinType::ULong: 370 return T == C.LongTy ? Match : NoMatch; 371 case BuiltinType::LongLong: 372 return T == C.UnsignedLongLongTy ? Match : NoMatch; 373 case BuiltinType::ULongLong: 374 return T == C.LongLongTy ? Match : NoMatch; 375 } 376 return NoMatch; 377 } 378 379 case CStrTy: { 380 const PointerType *PT = argTy->getAs<PointerType>(); 381 if (!PT) 382 return NoMatch; 383 QualType pointeeTy = PT->getPointeeType(); 384 if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 385 switch (BT->getKind()) { 386 case BuiltinType::Void: 387 case BuiltinType::Char_U: 388 case BuiltinType::UChar: 389 case BuiltinType::Char_S: 390 case BuiltinType::SChar: 391 return Match; 392 default: 393 break; 394 } 395 396 return NoMatch; 397 } 398 399 case WCStrTy: { 400 const PointerType *PT = argTy->getAs<PointerType>(); 401 if (!PT) 402 return NoMatch; 403 QualType pointeeTy = 404 C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 405 return pointeeTy == C.getWideCharType() ? Match : NoMatch; 406 } 407 408 case WIntTy: { 409 QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); 410 411 if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt) 412 return Match; 413 414 QualType PromoArg = argTy->isPromotableIntegerType() 415 ? C.getPromotedIntegerType(argTy) 416 : argTy; 417 PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); 418 419 // If the promoted argument is the corresponding signed type of the 420 // wint_t type, then it should match. 421 if (PromoArg->hasSignedIntegerRepresentation() && 422 C.getCorrespondingUnsignedType(PromoArg) == WInt) 423 return Match; 424 425 return WInt == PromoArg ? Match : NoMatch; 426 } 427 428 case CPointerTy: 429 if (argTy->isVoidPointerType()) { 430 return Match; 431 } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() || 432 argTy->isBlockPointerType() || argTy->isNullPtrType()) { 433 return NoMatchPedantic; 434 } else { 435 return NoMatch; 436 } 437 438 case ObjCPointerTy: { 439 if (argTy->getAs<ObjCObjectPointerType>() || 440 argTy->getAs<BlockPointerType>()) 441 return Match; 442 443 // Handle implicit toll-free bridging. 444 if (const PointerType *PT = argTy->getAs<PointerType>()) { 445 // Things such as CFTypeRef are really just opaque pointers 446 // to C structs representing CF types that can often be bridged 447 // to Objective-C objects. Since the compiler doesn't know which 448 // structs can be toll-free bridged, we just accept them all. 449 QualType pointee = PT->getPointeeType(); 450 if (pointee->getAsStructureType() || pointee->isVoidType()) 451 return Match; 452 } 453 return NoMatch; 454 } 455 } 456 457 llvm_unreachable("Invalid ArgType Kind!"); 458 } 459 460 QualType ArgType::getRepresentativeType(ASTContext &C) const { 461 QualType Res; 462 switch (K) { 463 case InvalidTy: 464 llvm_unreachable("No representative type for Invalid ArgType"); 465 case UnknownTy: 466 llvm_unreachable("No representative type for Unknown ArgType"); 467 case AnyCharTy: 468 Res = C.CharTy; 469 break; 470 case SpecificTy: 471 Res = T; 472 break; 473 case CStrTy: 474 Res = C.getPointerType(C.CharTy); 475 break; 476 case WCStrTy: 477 Res = C.getPointerType(C.getWideCharType()); 478 break; 479 case ObjCPointerTy: 480 Res = C.ObjCBuiltinIdTy; 481 break; 482 case CPointerTy: 483 Res = C.VoidPtrTy; 484 break; 485 case WIntTy: { 486 Res = C.getWIntType(); 487 break; 488 } 489 } 490 491 if (Ptr) 492 Res = C.getPointerType(Res); 493 return Res; 494 } 495 496 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const { 497 std::string S = getRepresentativeType(C).getAsString(); 498 499 std::string Alias; 500 if (Name) { 501 // Use a specific name for this type, e.g. "size_t". 502 Alias = Name; 503 if (Ptr) { 504 // If ArgType is actually a pointer to T, append an asterisk. 505 Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *"; 506 } 507 // If Alias is the same as the underlying type, e.g. wchar_t, then drop it. 508 if (S == Alias) 509 Alias.clear(); 510 } 511 512 if (!Alias.empty()) 513 return std::string("'") + Alias + "' (aka '" + S + "')"; 514 return std::string("'") + S + "'"; 515 } 516 517 518 //===----------------------------------------------------------------------===// 519 // Methods on OptionalAmount. 520 //===----------------------------------------------------------------------===// 521 522 ArgType 523 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { 524 return Ctx.IntTy; 525 } 526 527 //===----------------------------------------------------------------------===// 528 // Methods on LengthModifier. 529 //===----------------------------------------------------------------------===// 530 531 const char * 532 analyze_format_string::LengthModifier::toString() const { 533 switch (kind) { 534 case AsChar: 535 return "hh"; 536 case AsShort: 537 return "h"; 538 case AsLong: // or AsWideChar 539 return "l"; 540 case AsLongLong: 541 return "ll"; 542 case AsQuad: 543 return "q"; 544 case AsIntMax: 545 return "j"; 546 case AsSizeT: 547 return "z"; 548 case AsPtrDiff: 549 return "t"; 550 case AsInt32: 551 return "I32"; 552 case AsInt3264: 553 return "I"; 554 case AsInt64: 555 return "I64"; 556 case AsLongDouble: 557 return "L"; 558 case AsAllocate: 559 return "a"; 560 case AsMAllocate: 561 return "m"; 562 case AsWide: 563 return "w"; 564 case None: 565 return ""; 566 } 567 return nullptr; 568 } 569 570 //===----------------------------------------------------------------------===// 571 // Methods on ConversionSpecifier. 572 //===----------------------------------------------------------------------===// 573 574 const char *ConversionSpecifier::toString() const { 575 switch (kind) { 576 case dArg: return "d"; 577 case DArg: return "D"; 578 case iArg: return "i"; 579 case oArg: return "o"; 580 case OArg: return "O"; 581 case uArg: return "u"; 582 case UArg: return "U"; 583 case xArg: return "x"; 584 case XArg: return "X"; 585 case fArg: return "f"; 586 case FArg: return "F"; 587 case eArg: return "e"; 588 case EArg: return "E"; 589 case gArg: return "g"; 590 case GArg: return "G"; 591 case aArg: return "a"; 592 case AArg: return "A"; 593 case cArg: return "c"; 594 case sArg: return "s"; 595 case pArg: return "p"; 596 case PArg: 597 return "P"; 598 case nArg: return "n"; 599 case PercentArg: return "%"; 600 case ScanListArg: return "["; 601 case InvalidSpecifier: return nullptr; 602 603 // POSIX unicode extensions. 604 case CArg: return "C"; 605 case SArg: return "S"; 606 607 // Objective-C specific specifiers. 608 case ObjCObjArg: return "@"; 609 610 // FreeBSD kernel specific specifiers. 611 case FreeBSDbArg: return "b"; 612 case FreeBSDDArg: return "D"; 613 case FreeBSDrArg: return "r"; 614 case FreeBSDyArg: return "y"; 615 616 // GlibC specific specifiers. 617 case PrintErrno: return "m"; 618 619 // MS specific specifiers. 620 case ZArg: return "Z"; 621 } 622 return nullptr; 623 } 624 625 Optional<ConversionSpecifier> 626 ConversionSpecifier::getStandardSpecifier() const { 627 ConversionSpecifier::Kind NewKind; 628 629 switch (getKind()) { 630 default: 631 return None; 632 case DArg: 633 NewKind = dArg; 634 break; 635 case UArg: 636 NewKind = uArg; 637 break; 638 case OArg: 639 NewKind = oArg; 640 break; 641 } 642 643 ConversionSpecifier FixedCS(*this); 644 FixedCS.setKind(NewKind); 645 return FixedCS; 646 } 647 648 //===----------------------------------------------------------------------===// 649 // Methods on OptionalAmount. 650 //===----------------------------------------------------------------------===// 651 652 void OptionalAmount::toString(raw_ostream &os) const { 653 switch (hs) { 654 case Invalid: 655 case NotSpecified: 656 return; 657 case Arg: 658 if (UsesDotPrefix) 659 os << "."; 660 if (usesPositionalArg()) 661 os << "*" << getPositionalArgIndex() << "$"; 662 else 663 os << "*"; 664 break; 665 case Constant: 666 if (UsesDotPrefix) 667 os << "."; 668 os << amt; 669 break; 670 } 671 } 672 673 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { 674 switch (LM.getKind()) { 675 case LengthModifier::None: 676 return true; 677 678 // Handle most integer flags 679 case LengthModifier::AsShort: 680 if (Target.getTriple().isOSMSVCRT()) { 681 switch (CS.getKind()) { 682 case ConversionSpecifier::cArg: 683 case ConversionSpecifier::CArg: 684 case ConversionSpecifier::sArg: 685 case ConversionSpecifier::SArg: 686 case ConversionSpecifier::ZArg: 687 return true; 688 default: 689 break; 690 } 691 } 692 LLVM_FALLTHROUGH; 693 case LengthModifier::AsChar: 694 case LengthModifier::AsLongLong: 695 case LengthModifier::AsQuad: 696 case LengthModifier::AsIntMax: 697 case LengthModifier::AsSizeT: 698 case LengthModifier::AsPtrDiff: 699 switch (CS.getKind()) { 700 case ConversionSpecifier::dArg: 701 case ConversionSpecifier::DArg: 702 case ConversionSpecifier::iArg: 703 case ConversionSpecifier::oArg: 704 case ConversionSpecifier::OArg: 705 case ConversionSpecifier::uArg: 706 case ConversionSpecifier::UArg: 707 case ConversionSpecifier::xArg: 708 case ConversionSpecifier::XArg: 709 case ConversionSpecifier::nArg: 710 return true; 711 case ConversionSpecifier::FreeBSDrArg: 712 case ConversionSpecifier::FreeBSDyArg: 713 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 714 default: 715 return false; 716 } 717 718 // Handle 'l' flag 719 case LengthModifier::AsLong: // or AsWideChar 720 switch (CS.getKind()) { 721 case ConversionSpecifier::dArg: 722 case ConversionSpecifier::DArg: 723 case ConversionSpecifier::iArg: 724 case ConversionSpecifier::oArg: 725 case ConversionSpecifier::OArg: 726 case ConversionSpecifier::uArg: 727 case ConversionSpecifier::UArg: 728 case ConversionSpecifier::xArg: 729 case ConversionSpecifier::XArg: 730 case ConversionSpecifier::aArg: 731 case ConversionSpecifier::AArg: 732 case ConversionSpecifier::fArg: 733 case ConversionSpecifier::FArg: 734 case ConversionSpecifier::eArg: 735 case ConversionSpecifier::EArg: 736 case ConversionSpecifier::gArg: 737 case ConversionSpecifier::GArg: 738 case ConversionSpecifier::nArg: 739 case ConversionSpecifier::cArg: 740 case ConversionSpecifier::sArg: 741 case ConversionSpecifier::ScanListArg: 742 case ConversionSpecifier::ZArg: 743 return true; 744 case ConversionSpecifier::FreeBSDrArg: 745 case ConversionSpecifier::FreeBSDyArg: 746 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 747 default: 748 return false; 749 } 750 751 case LengthModifier::AsLongDouble: 752 switch (CS.getKind()) { 753 case ConversionSpecifier::aArg: 754 case ConversionSpecifier::AArg: 755 case ConversionSpecifier::fArg: 756 case ConversionSpecifier::FArg: 757 case ConversionSpecifier::eArg: 758 case ConversionSpecifier::EArg: 759 case ConversionSpecifier::gArg: 760 case ConversionSpecifier::GArg: 761 return true; 762 // GNU libc extension. 763 case ConversionSpecifier::dArg: 764 case ConversionSpecifier::iArg: 765 case ConversionSpecifier::oArg: 766 case ConversionSpecifier::uArg: 767 case ConversionSpecifier::xArg: 768 case ConversionSpecifier::XArg: 769 return !Target.getTriple().isOSDarwin() && 770 !Target.getTriple().isOSWindows(); 771 default: 772 return false; 773 } 774 775 case LengthModifier::AsAllocate: 776 switch (CS.getKind()) { 777 case ConversionSpecifier::sArg: 778 case ConversionSpecifier::SArg: 779 case ConversionSpecifier::ScanListArg: 780 return true; 781 default: 782 return false; 783 } 784 785 case LengthModifier::AsMAllocate: 786 switch (CS.getKind()) { 787 case ConversionSpecifier::cArg: 788 case ConversionSpecifier::CArg: 789 case ConversionSpecifier::sArg: 790 case ConversionSpecifier::SArg: 791 case ConversionSpecifier::ScanListArg: 792 return true; 793 default: 794 return false; 795 } 796 case LengthModifier::AsInt32: 797 case LengthModifier::AsInt3264: 798 case LengthModifier::AsInt64: 799 switch (CS.getKind()) { 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().isOSMSVCRT(); 807 default: 808 return false; 809 } 810 case LengthModifier::AsWide: 811 switch (CS.getKind()) { 812 case ConversionSpecifier::cArg: 813 case ConversionSpecifier::CArg: 814 case ConversionSpecifier::sArg: 815 case ConversionSpecifier::SArg: 816 case ConversionSpecifier::ZArg: 817 return Target.getTriple().isOSMSVCRT(); 818 default: 819 return false; 820 } 821 } 822 llvm_unreachable("Invalid LengthModifier Kind!"); 823 } 824 825 bool FormatSpecifier::hasStandardLengthModifier() const { 826 switch (LM.getKind()) { 827 case LengthModifier::None: 828 case LengthModifier::AsChar: 829 case LengthModifier::AsShort: 830 case LengthModifier::AsLong: 831 case LengthModifier::AsLongLong: 832 case LengthModifier::AsIntMax: 833 case LengthModifier::AsSizeT: 834 case LengthModifier::AsPtrDiff: 835 case LengthModifier::AsLongDouble: 836 return true; 837 case LengthModifier::AsAllocate: 838 case LengthModifier::AsMAllocate: 839 case LengthModifier::AsQuad: 840 case LengthModifier::AsInt32: 841 case LengthModifier::AsInt3264: 842 case LengthModifier::AsInt64: 843 case LengthModifier::AsWide: 844 return false; 845 } 846 llvm_unreachable("Invalid LengthModifier Kind!"); 847 } 848 849 bool FormatSpecifier::hasStandardConversionSpecifier( 850 const LangOptions &LangOpt) const { 851 switch (CS.getKind()) { 852 case ConversionSpecifier::cArg: 853 case ConversionSpecifier::dArg: 854 case ConversionSpecifier::iArg: 855 case ConversionSpecifier::oArg: 856 case ConversionSpecifier::uArg: 857 case ConversionSpecifier::xArg: 858 case ConversionSpecifier::XArg: 859 case ConversionSpecifier::fArg: 860 case ConversionSpecifier::FArg: 861 case ConversionSpecifier::eArg: 862 case ConversionSpecifier::EArg: 863 case ConversionSpecifier::gArg: 864 case ConversionSpecifier::GArg: 865 case ConversionSpecifier::aArg: 866 case ConversionSpecifier::AArg: 867 case ConversionSpecifier::sArg: 868 case ConversionSpecifier::pArg: 869 case ConversionSpecifier::nArg: 870 case ConversionSpecifier::ObjCObjArg: 871 case ConversionSpecifier::ScanListArg: 872 case ConversionSpecifier::PercentArg: 873 case ConversionSpecifier::PArg: 874 return true; 875 case ConversionSpecifier::CArg: 876 case ConversionSpecifier::SArg: 877 return LangOpt.ObjC; 878 case ConversionSpecifier::InvalidSpecifier: 879 case ConversionSpecifier::FreeBSDbArg: 880 case ConversionSpecifier::FreeBSDDArg: 881 case ConversionSpecifier::FreeBSDrArg: 882 case ConversionSpecifier::FreeBSDyArg: 883 case ConversionSpecifier::PrintErrno: 884 case ConversionSpecifier::DArg: 885 case ConversionSpecifier::OArg: 886 case ConversionSpecifier::UArg: 887 case ConversionSpecifier::ZArg: 888 return false; 889 } 890 llvm_unreachable("Invalid ConversionSpecifier Kind!"); 891 } 892 893 bool FormatSpecifier::hasStandardLengthConversionCombination() const { 894 if (LM.getKind() == LengthModifier::AsLongDouble) { 895 switch(CS.getKind()) { 896 case ConversionSpecifier::dArg: 897 case ConversionSpecifier::iArg: 898 case ConversionSpecifier::oArg: 899 case ConversionSpecifier::uArg: 900 case ConversionSpecifier::xArg: 901 case ConversionSpecifier::XArg: 902 return false; 903 default: 904 return true; 905 } 906 } 907 return true; 908 } 909 910 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { 911 if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { 912 if (LM.getKind() == LengthModifier::AsLongDouble || 913 LM.getKind() == LengthModifier::AsQuad) { 914 LengthModifier FixedLM(LM); 915 FixedLM.setKind(LengthModifier::AsLongLong); 916 return FixedLM; 917 } 918 } 919 920 return None; 921 } 922 923 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 924 LengthModifier &LM) { 925 assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 926 const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 927 928 for (;;) { 929 const IdentifierInfo *Identifier = Typedef->getIdentifier(); 930 if (Identifier->getName() == "size_t") { 931 LM.setKind(LengthModifier::AsSizeT); 932 return true; 933 } else if (Identifier->getName() == "ssize_t") { 934 // Not C99, but common in Unix. 935 LM.setKind(LengthModifier::AsSizeT); 936 return true; 937 } else if (Identifier->getName() == "intmax_t") { 938 LM.setKind(LengthModifier::AsIntMax); 939 return true; 940 } else if (Identifier->getName() == "uintmax_t") { 941 LM.setKind(LengthModifier::AsIntMax); 942 return true; 943 } else if (Identifier->getName() == "ptrdiff_t") { 944 LM.setKind(LengthModifier::AsPtrDiff); 945 return true; 946 } 947 948 QualType T = Typedef->getUnderlyingType(); 949 if (!isa<TypedefType>(T)) 950 break; 951 952 Typedef = cast<TypedefType>(T)->getDecl(); 953 } 954 return false; 955 } 956