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