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