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