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 // OpenCL specific specifiers. 623 case VArg: return "v"; 624 } 625 return nullptr; 626 } 627 628 Optional<ConversionSpecifier> 629 ConversionSpecifier::getStandardSpecifier() const { 630 ConversionSpecifier::Kind NewKind; 631 632 switch (getKind()) { 633 default: 634 return None; 635 case DArg: 636 NewKind = dArg; 637 break; 638 case UArg: 639 NewKind = uArg; 640 break; 641 case OArg: 642 NewKind = oArg; 643 break; 644 } 645 646 ConversionSpecifier FixedCS(*this); 647 FixedCS.setKind(NewKind); 648 return FixedCS; 649 } 650 651 //===----------------------------------------------------------------------===// 652 // Methods on OptionalAmount. 653 //===----------------------------------------------------------------------===// 654 655 void OptionalAmount::toString(raw_ostream &os) const { 656 switch (hs) { 657 case Invalid: 658 case NotSpecified: 659 return; 660 case Arg: 661 if (UsesDotPrefix) 662 os << "."; 663 if (usesPositionalArg()) 664 os << "*" << getPositionalArgIndex() << "$"; 665 else 666 os << "*"; 667 break; 668 case Constant: 669 if (UsesDotPrefix) 670 os << "."; 671 os << amt; 672 break; 673 } 674 } 675 676 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { 677 switch (LM.getKind()) { 678 case LengthModifier::None: 679 return true; 680 681 // Handle most integer flags 682 case LengthModifier::AsShort: 683 if (Target.getTriple().isOSMSVCRT()) { 684 switch (CS.getKind()) { 685 case ConversionSpecifier::cArg: 686 case ConversionSpecifier::CArg: 687 case ConversionSpecifier::sArg: 688 case ConversionSpecifier::SArg: 689 case ConversionSpecifier::ZArg: 690 return true; 691 default: 692 break; 693 } 694 } 695 LLVM_FALLTHROUGH; 696 case LengthModifier::AsChar: 697 case LengthModifier::AsLongLong: 698 case LengthModifier::AsQuad: 699 case LengthModifier::AsIntMax: 700 case LengthModifier::AsSizeT: 701 case LengthModifier::AsPtrDiff: 702 switch (CS.getKind()) { 703 case ConversionSpecifier::dArg: 704 case ConversionSpecifier::DArg: 705 case ConversionSpecifier::iArg: 706 case ConversionSpecifier::oArg: 707 case ConversionSpecifier::OArg: 708 case ConversionSpecifier::uArg: 709 case ConversionSpecifier::UArg: 710 case ConversionSpecifier::xArg: 711 case ConversionSpecifier::XArg: 712 case ConversionSpecifier::nArg: 713 return true; 714 case ConversionSpecifier::FreeBSDrArg: 715 case ConversionSpecifier::FreeBSDyArg: 716 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 717 default: 718 return false; 719 } 720 721 // Handle 'l' flag 722 case LengthModifier::AsLong: // or AsWideChar 723 switch (CS.getKind()) { 724 case ConversionSpecifier::dArg: 725 case ConversionSpecifier::DArg: 726 case ConversionSpecifier::iArg: 727 case ConversionSpecifier::oArg: 728 case ConversionSpecifier::OArg: 729 case ConversionSpecifier::uArg: 730 case ConversionSpecifier::UArg: 731 case ConversionSpecifier::xArg: 732 case ConversionSpecifier::XArg: 733 case ConversionSpecifier::aArg: 734 case ConversionSpecifier::AArg: 735 case ConversionSpecifier::fArg: 736 case ConversionSpecifier::FArg: 737 case ConversionSpecifier::eArg: 738 case ConversionSpecifier::EArg: 739 case ConversionSpecifier::gArg: 740 case ConversionSpecifier::GArg: 741 case ConversionSpecifier::nArg: 742 case ConversionSpecifier::cArg: 743 case ConversionSpecifier::sArg: 744 case ConversionSpecifier::ScanListArg: 745 case ConversionSpecifier::ZArg: 746 return true; 747 case ConversionSpecifier::FreeBSDrArg: 748 case ConversionSpecifier::FreeBSDyArg: 749 return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); 750 default: 751 return false; 752 } 753 754 case LengthModifier::AsLongDouble: 755 switch (CS.getKind()) { 756 case ConversionSpecifier::aArg: 757 case ConversionSpecifier::AArg: 758 case ConversionSpecifier::fArg: 759 case ConversionSpecifier::FArg: 760 case ConversionSpecifier::eArg: 761 case ConversionSpecifier::EArg: 762 case ConversionSpecifier::gArg: 763 case ConversionSpecifier::GArg: 764 return true; 765 // GNU libc extension. 766 case ConversionSpecifier::dArg: 767 case ConversionSpecifier::iArg: 768 case ConversionSpecifier::oArg: 769 case ConversionSpecifier::uArg: 770 case ConversionSpecifier::xArg: 771 case ConversionSpecifier::XArg: 772 return !Target.getTriple().isOSDarwin() && 773 !Target.getTriple().isOSWindows(); 774 default: 775 return false; 776 } 777 778 case LengthModifier::AsAllocate: 779 switch (CS.getKind()) { 780 case ConversionSpecifier::sArg: 781 case ConversionSpecifier::SArg: 782 case ConversionSpecifier::ScanListArg: 783 return true; 784 default: 785 return false; 786 } 787 788 case LengthModifier::AsMAllocate: 789 switch (CS.getKind()) { 790 case ConversionSpecifier::cArg: 791 case ConversionSpecifier::CArg: 792 case ConversionSpecifier::sArg: 793 case ConversionSpecifier::SArg: 794 case ConversionSpecifier::ScanListArg: 795 return true; 796 default: 797 return false; 798 } 799 case LengthModifier::AsInt32: 800 case LengthModifier::AsInt3264: 801 case LengthModifier::AsInt64: 802 switch (CS.getKind()) { 803 case ConversionSpecifier::dArg: 804 case ConversionSpecifier::iArg: 805 case ConversionSpecifier::oArg: 806 case ConversionSpecifier::uArg: 807 case ConversionSpecifier::xArg: 808 case ConversionSpecifier::XArg: 809 return Target.getTriple().isOSMSVCRT(); 810 default: 811 return false; 812 } 813 case LengthModifier::AsWide: 814 switch (CS.getKind()) { 815 case ConversionSpecifier::cArg: 816 case ConversionSpecifier::CArg: 817 case ConversionSpecifier::sArg: 818 case ConversionSpecifier::SArg: 819 case ConversionSpecifier::ZArg: 820 return Target.getTriple().isOSMSVCRT(); 821 default: 822 return false; 823 } 824 } 825 llvm_unreachable("Invalid LengthModifier Kind!"); 826 } 827 828 bool FormatSpecifier::hasStandardLengthModifier() const { 829 switch (LM.getKind()) { 830 case LengthModifier::None: 831 case LengthModifier::AsChar: 832 case LengthModifier::AsShort: 833 case LengthModifier::AsLong: 834 case LengthModifier::AsLongLong: 835 case LengthModifier::AsIntMax: 836 case LengthModifier::AsSizeT: 837 case LengthModifier::AsPtrDiff: 838 case LengthModifier::AsLongDouble: 839 return true; 840 case LengthModifier::AsAllocate: 841 case LengthModifier::AsMAllocate: 842 case LengthModifier::AsQuad: 843 case LengthModifier::AsInt32: 844 case LengthModifier::AsInt3264: 845 case LengthModifier::AsInt64: 846 case LengthModifier::AsWide: 847 return false; 848 } 849 llvm_unreachable("Invalid LengthModifier Kind!"); 850 } 851 852 bool FormatSpecifier::hasStandardConversionSpecifier( 853 const LangOptions &LangOpt) const { 854 switch (CS.getKind()) { 855 case ConversionSpecifier::cArg: 856 case ConversionSpecifier::dArg: 857 case ConversionSpecifier::iArg: 858 case ConversionSpecifier::oArg: 859 case ConversionSpecifier::uArg: 860 case ConversionSpecifier::xArg: 861 case ConversionSpecifier::XArg: 862 case ConversionSpecifier::fArg: 863 case ConversionSpecifier::FArg: 864 case ConversionSpecifier::eArg: 865 case ConversionSpecifier::EArg: 866 case ConversionSpecifier::gArg: 867 case ConversionSpecifier::GArg: 868 case ConversionSpecifier::aArg: 869 case ConversionSpecifier::AArg: 870 case ConversionSpecifier::sArg: 871 case ConversionSpecifier::pArg: 872 case ConversionSpecifier::nArg: 873 case ConversionSpecifier::ObjCObjArg: 874 case ConversionSpecifier::ScanListArg: 875 case ConversionSpecifier::PercentArg: 876 case ConversionSpecifier::PArg: 877 return true; 878 case ConversionSpecifier::CArg: 879 case ConversionSpecifier::SArg: 880 return LangOpt.ObjC; 881 case ConversionSpecifier::VArg: 882 return LangOpt.OpenCL; 883 case ConversionSpecifier::InvalidSpecifier: 884 case ConversionSpecifier::FreeBSDbArg: 885 case ConversionSpecifier::FreeBSDDArg: 886 case ConversionSpecifier::FreeBSDrArg: 887 case ConversionSpecifier::FreeBSDyArg: 888 case ConversionSpecifier::PrintErrno: 889 case ConversionSpecifier::DArg: 890 case ConversionSpecifier::OArg: 891 case ConversionSpecifier::UArg: 892 case ConversionSpecifier::ZArg: 893 return false; 894 } 895 llvm_unreachable("Invalid ConversionSpecifier Kind!"); 896 } 897 898 bool FormatSpecifier::hasStandardLengthConversionCombination() const { 899 if (LM.getKind() == LengthModifier::AsLongDouble) { 900 switch(CS.getKind()) { 901 case ConversionSpecifier::dArg: 902 case ConversionSpecifier::iArg: 903 case ConversionSpecifier::oArg: 904 case ConversionSpecifier::uArg: 905 case ConversionSpecifier::xArg: 906 case ConversionSpecifier::XArg: 907 return false; 908 default: 909 return true; 910 } 911 } 912 return true; 913 } 914 915 Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { 916 if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { 917 if (LM.getKind() == LengthModifier::AsLongDouble || 918 LM.getKind() == LengthModifier::AsQuad) { 919 LengthModifier FixedLM(LM); 920 FixedLM.setKind(LengthModifier::AsLongLong); 921 return FixedLM; 922 } 923 } 924 925 return None; 926 } 927 928 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 929 LengthModifier &LM) { 930 assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 931 const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 932 933 for (;;) { 934 const IdentifierInfo *Identifier = Typedef->getIdentifier(); 935 if (Identifier->getName() == "size_t") { 936 LM.setKind(LengthModifier::AsSizeT); 937 return true; 938 } else if (Identifier->getName() == "ssize_t") { 939 // Not C99, but common in Unix. 940 LM.setKind(LengthModifier::AsSizeT); 941 return true; 942 } else if (Identifier->getName() == "intmax_t") { 943 LM.setKind(LengthModifier::AsIntMax); 944 return true; 945 } else if (Identifier->getName() == "uintmax_t") { 946 LM.setKind(LengthModifier::AsIntMax); 947 return true; 948 } else if (Identifier->getName() == "ptrdiff_t") { 949 LM.setKind(LengthModifier::AsPtrDiff); 950 return true; 951 } 952 953 QualType T = Typedef->getUnderlyingType(); 954 if (!isa<TypedefType>(T)) 955 break; 956 957 Typedef = cast<TypedefType>(T)->getDecl(); 958 } 959 return false; 960 } 961