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