1 //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Handling of format string in printf and friends. The structure of format 11 // strings for fprintf() are described in C99 7.19.6.1. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/AST/FormatString.h" 16 #include "clang/AST/OSLog.h" 17 #include "FormatStringParsing.h" 18 #include "clang/Basic/TargetInfo.h" 19 20 using clang::analyze_format_string::ArgType; 21 using clang::analyze_format_string::FormatStringHandler; 22 using clang::analyze_format_string::LengthModifier; 23 using clang::analyze_format_string::OptionalAmount; 24 using clang::analyze_format_string::ConversionSpecifier; 25 using clang::analyze_printf::PrintfSpecifier; 26 27 using namespace clang; 28 29 typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 30 PrintfSpecifierResult; 31 32 //===----------------------------------------------------------------------===// 33 // Methods for parsing format strings. 34 //===----------------------------------------------------------------------===// 35 36 using analyze_format_string::ParseNonPositionAmount; 37 38 static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 39 const char *Start, const char *&Beg, const char *E, 40 unsigned *argIndex) { 41 if (argIndex) { 42 FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 43 } else { 44 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 45 analyze_format_string::PrecisionPos); 46 if (Amt.isInvalid()) 47 return true; 48 FS.setPrecision(Amt); 49 } 50 return false; 51 } 52 53 static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS, 54 const char *FlagBeg, const char *E, bool Warn) { 55 StringRef Flag(FlagBeg, E - FlagBeg); 56 // Currently there is only one flag. 57 if (Flag == "tt") { 58 FS.setHasObjCTechnicalTerm(FlagBeg); 59 return false; 60 } 61 // Handle either the case of no flag or an invalid flag. 62 if (Warn) { 63 if (Flag == "") 64 H.HandleEmptyObjCModifierFlag(FlagBeg, E - FlagBeg); 65 else 66 H.HandleInvalidObjCModifierFlag(FlagBeg, E - FlagBeg); 67 } 68 return true; 69 } 70 71 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 72 const char *&Beg, 73 const char *E, 74 unsigned &argIndex, 75 const LangOptions &LO, 76 const TargetInfo &Target, 77 bool Warn, 78 bool isFreeBSDKPrintf) { 79 80 using namespace clang::analyze_format_string; 81 using namespace clang::analyze_printf; 82 83 const char *I = Beg; 84 const char *Start = nullptr; 85 UpdateOnReturn <const char*> UpdateBeg(Beg, I); 86 87 // Look for a '%' character that indicates the start of a format specifier. 88 for ( ; I != E ; ++I) { 89 char c = *I; 90 if (c == '\0') { 91 // Detect spurious null characters, which are likely errors. 92 H.HandleNullChar(I); 93 return true; 94 } 95 if (c == '%') { 96 Start = I++; // Record the start of the format specifier. 97 break; 98 } 99 } 100 101 // No format specifier found? 102 if (!Start) 103 return false; 104 105 if (I == E) { 106 // No more characters left? 107 if (Warn) 108 H.HandleIncompleteSpecifier(Start, E - Start); 109 return true; 110 } 111 112 PrintfSpecifier FS; 113 if (ParseArgPosition(H, FS, Start, I, E)) 114 return true; 115 116 if (I == E) { 117 // No more characters left? 118 if (Warn) 119 H.HandleIncompleteSpecifier(Start, E - Start); 120 return true; 121 } 122 123 if (*I == '{') { 124 ++I; 125 unsigned char PrivacyFlags = 0; 126 StringRef MatchedStr; 127 128 do { 129 StringRef Str(I, E - I); 130 std::string Match = "^[[:space:]]*(private|public|sensitive)" 131 "[[:space:]]*(,|})"; 132 llvm::Regex R(Match); 133 SmallVector<StringRef, 2> Matches; 134 135 if (R.match(Str, &Matches)) { 136 MatchedStr = Matches[1]; 137 I += Matches[0].size(); 138 139 // Set the privacy flag if the privacy annotation in the 140 // comma-delimited segment is at least as strict as the privacy 141 // annotations in previous comma-delimited segments. 142 if (MatchedStr.equals("sensitive")) 143 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsSensitive; 144 else if (PrivacyFlags != 145 clang::analyze_os_log::OSLogBufferItem::IsSensitive && 146 MatchedStr.equals("private")) 147 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate; 148 else if (PrivacyFlags == 0 && MatchedStr.equals("public")) 149 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic; 150 } else { 151 size_t CommaOrBracePos = 152 Str.find_if([](char c) { return c == ',' || c == '}'; }); 153 154 if (CommaOrBracePos == StringRef::npos) { 155 // Neither a comma nor the closing brace was found. 156 if (Warn) 157 H.HandleIncompleteSpecifier(Start, E - Start); 158 return true; 159 } 160 161 I += CommaOrBracePos + 1; 162 } 163 // Continue until the closing brace is found. 164 } while (*(I - 1) == ','); 165 166 // Set the privacy flag. 167 switch (PrivacyFlags) { 168 case 0: 169 break; 170 case clang::analyze_os_log::OSLogBufferItem::IsPrivate: 171 FS.setIsPrivate(MatchedStr.data()); 172 break; 173 case clang::analyze_os_log::OSLogBufferItem::IsPublic: 174 FS.setIsPublic(MatchedStr.data()); 175 break; 176 case clang::analyze_os_log::OSLogBufferItem::IsSensitive: 177 FS.setIsSensitive(MatchedStr.data()); 178 break; 179 default: 180 llvm_unreachable("Unexpected privacy flag value"); 181 } 182 } 183 184 // Look for flags (if any). 185 bool hasMore = true; 186 for ( ; I != E; ++I) { 187 switch (*I) { 188 default: hasMore = false; break; 189 case '\'': 190 // FIXME: POSIX specific. Always accept? 191 FS.setHasThousandsGrouping(I); 192 break; 193 case '-': FS.setIsLeftJustified(I); break; 194 case '+': FS.setHasPlusPrefix(I); break; 195 case ' ': FS.setHasSpacePrefix(I); break; 196 case '#': FS.setHasAlternativeForm(I); break; 197 case '0': FS.setHasLeadingZeros(I); break; 198 } 199 if (!hasMore) 200 break; 201 } 202 203 if (I == E) { 204 // No more characters left? 205 if (Warn) 206 H.HandleIncompleteSpecifier(Start, E - Start); 207 return true; 208 } 209 210 // Look for the field width (if any). 211 if (ParseFieldWidth(H, FS, Start, I, E, 212 FS.usesPositionalArg() ? nullptr : &argIndex)) 213 return true; 214 215 if (I == E) { 216 // No more characters left? 217 if (Warn) 218 H.HandleIncompleteSpecifier(Start, E - Start); 219 return true; 220 } 221 222 // Look for the precision (if any). 223 if (*I == '.') { 224 ++I; 225 if (I == E) { 226 if (Warn) 227 H.HandleIncompleteSpecifier(Start, E - Start); 228 return true; 229 } 230 231 if (ParsePrecision(H, FS, Start, I, E, 232 FS.usesPositionalArg() ? nullptr : &argIndex)) 233 return true; 234 235 if (I == E) { 236 // No more characters left? 237 if (Warn) 238 H.HandleIncompleteSpecifier(Start, E - Start); 239 return true; 240 } 241 } 242 243 // Look for the length modifier. 244 if (ParseLengthModifier(FS, I, E, LO) && I == E) { 245 // No more characters left? 246 if (Warn) 247 H.HandleIncompleteSpecifier(Start, E - Start); 248 return true; 249 } 250 251 // Look for the Objective-C modifier flags, if any. 252 // We parse these here, even if they don't apply to 253 // the conversion specifier, and then emit an error 254 // later if the conversion specifier isn't '@'. This 255 // enables better recovery, and we don't know if 256 // these flags are applicable until later. 257 const char *ObjCModifierFlagsStart = nullptr, 258 *ObjCModifierFlagsEnd = nullptr; 259 if (*I == '[') { 260 ObjCModifierFlagsStart = I; 261 ++I; 262 auto flagStart = I; 263 for (;; ++I) { 264 ObjCModifierFlagsEnd = I; 265 if (I == E) { 266 if (Warn) 267 H.HandleIncompleteSpecifier(Start, E - Start); 268 return true; 269 } 270 // Did we find the closing ']'? 271 if (*I == ']') { 272 if (ParseObjCFlags(H, FS, flagStart, I, Warn)) 273 return true; 274 ++I; 275 break; 276 } 277 // There are no separators defined yet for multiple 278 // Objective-C modifier flags. When those are 279 // defined, this is the place to check. 280 } 281 } 282 283 if (*I == '\0') { 284 // Detect spurious null characters, which are likely errors. 285 H.HandleNullChar(I); 286 return true; 287 } 288 289 // Finally, look for the conversion specifier. 290 const char *conversionPosition = I++; 291 ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 292 switch (*conversionPosition) { 293 default: 294 break; 295 // C99: 7.19.6.1 (section 8). 296 case '%': k = ConversionSpecifier::PercentArg; break; 297 case 'A': k = ConversionSpecifier::AArg; break; 298 case 'E': k = ConversionSpecifier::EArg; break; 299 case 'F': k = ConversionSpecifier::FArg; break; 300 case 'G': k = ConversionSpecifier::GArg; break; 301 case 'X': k = ConversionSpecifier::XArg; break; 302 case 'a': k = ConversionSpecifier::aArg; break; 303 case 'c': k = ConversionSpecifier::cArg; break; 304 case 'd': k = ConversionSpecifier::dArg; break; 305 case 'e': k = ConversionSpecifier::eArg; break; 306 case 'f': k = ConversionSpecifier::fArg; break; 307 case 'g': k = ConversionSpecifier::gArg; break; 308 case 'i': k = ConversionSpecifier::iArg; break; 309 case 'n': k = ConversionSpecifier::nArg; break; 310 case 'o': k = ConversionSpecifier::oArg; break; 311 case 'p': k = ConversionSpecifier::pArg; break; 312 case 's': k = ConversionSpecifier::sArg; break; 313 case 'u': k = ConversionSpecifier::uArg; break; 314 case 'x': k = ConversionSpecifier::xArg; break; 315 // POSIX specific. 316 case 'C': k = ConversionSpecifier::CArg; break; 317 case 'S': k = ConversionSpecifier::SArg; break; 318 // Apple extension for os_log 319 case 'P': 320 k = ConversionSpecifier::PArg; 321 break; 322 // Objective-C. 323 case '@': k = ConversionSpecifier::ObjCObjArg; break; 324 // Glibc specific. 325 case 'm': k = ConversionSpecifier::PrintErrno; break; 326 // FreeBSD kernel specific. 327 case 'b': 328 if (isFreeBSDKPrintf) 329 k = ConversionSpecifier::FreeBSDbArg; // int followed by char * 330 break; 331 case 'r': 332 if (isFreeBSDKPrintf) 333 k = ConversionSpecifier::FreeBSDrArg; // int 334 break; 335 case 'y': 336 if (isFreeBSDKPrintf) 337 k = ConversionSpecifier::FreeBSDyArg; // int 338 break; 339 // Apple-specific. 340 case 'D': 341 if (isFreeBSDKPrintf) 342 k = ConversionSpecifier::FreeBSDDArg; // void * followed by char * 343 else if (Target.getTriple().isOSDarwin()) 344 k = ConversionSpecifier::DArg; 345 break; 346 case 'O': 347 if (Target.getTriple().isOSDarwin()) 348 k = ConversionSpecifier::OArg; 349 break; 350 case 'U': 351 if (Target.getTriple().isOSDarwin()) 352 k = ConversionSpecifier::UArg; 353 break; 354 // MS specific. 355 case 'Z': 356 if (Target.getTriple().isOSMSVCRT()) 357 k = ConversionSpecifier::ZArg; 358 } 359 360 // Check to see if we used the Objective-C modifier flags with 361 // a conversion specifier other than '@'. 362 if (k != ConversionSpecifier::ObjCObjArg && 363 k != ConversionSpecifier::InvalidSpecifier && 364 ObjCModifierFlagsStart) { 365 H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart, 366 ObjCModifierFlagsEnd + 1, 367 conversionPosition); 368 return true; 369 } 370 371 PrintfConversionSpecifier CS(conversionPosition, k); 372 FS.setConversionSpecifier(CS); 373 if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 374 FS.setArgIndex(argIndex++); 375 // FreeBSD kernel specific. 376 if (k == ConversionSpecifier::FreeBSDbArg || 377 k == ConversionSpecifier::FreeBSDDArg) 378 argIndex++; 379 380 if (k == ConversionSpecifier::InvalidSpecifier) { 381 unsigned Len = I - Start; 382 if (ParseUTF8InvalidSpecifier(Start, E, Len)) { 383 CS.setEndScanList(Start + Len); 384 FS.setConversionSpecifier(CS); 385 } 386 // Assume the conversion takes one argument. 387 return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len); 388 } 389 return PrintfSpecifierResult(Start, FS); 390 } 391 392 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 393 const char *I, 394 const char *E, 395 const LangOptions &LO, 396 const TargetInfo &Target, 397 bool isFreeBSDKPrintf) { 398 399 unsigned argIndex = 0; 400 401 // Keep looking for a format specifier until we have exhausted the string. 402 while (I != E) { 403 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 404 LO, Target, true, 405 isFreeBSDKPrintf); 406 // Did a fail-stop error of any kind occur when parsing the specifier? 407 // If so, don't do any more processing. 408 if (FSR.shouldStop()) 409 return true; 410 // Did we exhaust the string or encounter an error that 411 // we can recover from? 412 if (!FSR.hasValue()) 413 continue; 414 // We have a format specifier. Pass it to the callback. 415 if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 416 I - FSR.getStart())) 417 return true; 418 } 419 assert(I == E && "Format string not exhausted"); 420 return false; 421 } 422 423 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I, 424 const char *E, 425 const LangOptions &LO, 426 const TargetInfo &Target) { 427 428 unsigned argIndex = 0; 429 430 // Keep looking for a %s format specifier until we have exhausted the string. 431 FormatStringHandler H; 432 while (I != E) { 433 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 434 LO, Target, false, 435 false); 436 // Did a fail-stop error of any kind occur when parsing the specifier? 437 // If so, don't do any more processing. 438 if (FSR.shouldStop()) 439 return false; 440 // Did we exhaust the string or encounter an error that 441 // we can recover from? 442 if (!FSR.hasValue()) 443 continue; 444 const analyze_printf::PrintfSpecifier &FS = FSR.getValue(); 445 // Return true if this a %s format specifier. 446 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg) 447 return true; 448 } 449 return false; 450 } 451 452 //===----------------------------------------------------------------------===// 453 // Methods on PrintfSpecifier. 454 //===----------------------------------------------------------------------===// 455 456 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, 457 bool IsObjCLiteral) const { 458 const PrintfConversionSpecifier &CS = getConversionSpecifier(); 459 460 if (!CS.consumesDataArgument()) 461 return ArgType::Invalid(); 462 463 if (CS.getKind() == ConversionSpecifier::cArg) 464 switch (LM.getKind()) { 465 case LengthModifier::None: 466 return Ctx.IntTy; 467 case LengthModifier::AsLong: 468 case LengthModifier::AsWide: 469 return ArgType(ArgType::WIntTy, "wint_t"); 470 case LengthModifier::AsShort: 471 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT()) 472 return Ctx.IntTy; 473 LLVM_FALLTHROUGH; 474 default: 475 return ArgType::Invalid(); 476 } 477 478 if (CS.isIntArg()) 479 switch (LM.getKind()) { 480 case LengthModifier::AsLongDouble: 481 // GNU extension. 482 return Ctx.LongLongTy; 483 case LengthModifier::None: 484 return Ctx.IntTy; 485 case LengthModifier::AsInt32: 486 return ArgType(Ctx.IntTy, "__int32"); 487 case LengthModifier::AsChar: return ArgType::AnyCharTy; 488 case LengthModifier::AsShort: return Ctx.ShortTy; 489 case LengthModifier::AsLong: return Ctx.LongTy; 490 case LengthModifier::AsLongLong: 491 case LengthModifier::AsQuad: 492 return Ctx.LongLongTy; 493 case LengthModifier::AsInt64: 494 return ArgType(Ctx.LongLongTy, "__int64"); 495 case LengthModifier::AsIntMax: 496 return ArgType(Ctx.getIntMaxType(), "intmax_t"); 497 case LengthModifier::AsSizeT: 498 return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t")); 499 case LengthModifier::AsInt3264: 500 return Ctx.getTargetInfo().getTriple().isArch64Bit() 501 ? ArgType(Ctx.LongLongTy, "__int64") 502 : ArgType(Ctx.IntTy, "__int32"); 503 case LengthModifier::AsPtrDiff: 504 return ArgType::makePtrdiffT( 505 ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); 506 case LengthModifier::AsAllocate: 507 case LengthModifier::AsMAllocate: 508 case LengthModifier::AsWide: 509 return ArgType::Invalid(); 510 } 511 512 if (CS.isUIntArg()) 513 switch (LM.getKind()) { 514 case LengthModifier::AsLongDouble: 515 // GNU extension. 516 return Ctx.UnsignedLongLongTy; 517 case LengthModifier::None: 518 return Ctx.UnsignedIntTy; 519 case LengthModifier::AsInt32: 520 return ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 521 case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 522 case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 523 case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 524 case LengthModifier::AsLongLong: 525 case LengthModifier::AsQuad: 526 return Ctx.UnsignedLongLongTy; 527 case LengthModifier::AsInt64: 528 return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64"); 529 case LengthModifier::AsIntMax: 530 return ArgType(Ctx.getUIntMaxType(), "uintmax_t"); 531 case LengthModifier::AsSizeT: 532 return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t")); 533 case LengthModifier::AsInt3264: 534 return Ctx.getTargetInfo().getTriple().isArch64Bit() 535 ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64") 536 : ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 537 case LengthModifier::AsPtrDiff: 538 return ArgType::makePtrdiffT( 539 ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t")); 540 case LengthModifier::AsAllocate: 541 case LengthModifier::AsMAllocate: 542 case LengthModifier::AsWide: 543 return ArgType::Invalid(); 544 } 545 546 if (CS.isDoubleArg()) { 547 if (LM.getKind() == LengthModifier::AsLongDouble) 548 return Ctx.LongDoubleTy; 549 return Ctx.DoubleTy; 550 } 551 552 if (CS.getKind() == ConversionSpecifier::nArg) { 553 switch (LM.getKind()) { 554 case LengthModifier::None: 555 return ArgType::PtrTo(Ctx.IntTy); 556 case LengthModifier::AsChar: 557 return ArgType::PtrTo(Ctx.SignedCharTy); 558 case LengthModifier::AsShort: 559 return ArgType::PtrTo(Ctx.ShortTy); 560 case LengthModifier::AsLong: 561 return ArgType::PtrTo(Ctx.LongTy); 562 case LengthModifier::AsLongLong: 563 case LengthModifier::AsQuad: 564 return ArgType::PtrTo(Ctx.LongLongTy); 565 case LengthModifier::AsIntMax: 566 return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); 567 case LengthModifier::AsSizeT: 568 return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t")); 569 case LengthModifier::AsPtrDiff: 570 return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); 571 case LengthModifier::AsLongDouble: 572 return ArgType(); // FIXME: Is this a known extension? 573 case LengthModifier::AsAllocate: 574 case LengthModifier::AsMAllocate: 575 case LengthModifier::AsInt32: 576 case LengthModifier::AsInt3264: 577 case LengthModifier::AsInt64: 578 case LengthModifier::AsWide: 579 return ArgType::Invalid(); 580 } 581 } 582 583 switch (CS.getKind()) { 584 case ConversionSpecifier::sArg: 585 if (LM.getKind() == LengthModifier::AsWideChar) { 586 if (IsObjCLiteral) 587 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 588 "const unichar *"); 589 return ArgType(ArgType::WCStrTy, "wchar_t *"); 590 } 591 if (LM.getKind() == LengthModifier::AsWide) 592 return ArgType(ArgType::WCStrTy, "wchar_t *"); 593 return ArgType::CStrTy; 594 case ConversionSpecifier::SArg: 595 if (IsObjCLiteral) 596 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 597 "const unichar *"); 598 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() && 599 LM.getKind() == LengthModifier::AsShort) 600 return ArgType::CStrTy; 601 return ArgType(ArgType::WCStrTy, "wchar_t *"); 602 case ConversionSpecifier::CArg: 603 if (IsObjCLiteral) 604 return ArgType(Ctx.UnsignedShortTy, "unichar"); 605 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() && 606 LM.getKind() == LengthModifier::AsShort) 607 return Ctx.IntTy; 608 return ArgType(Ctx.WideCharTy, "wchar_t"); 609 case ConversionSpecifier::pArg: 610 case ConversionSpecifier::PArg: 611 return ArgType::CPointerTy; 612 case ConversionSpecifier::ObjCObjArg: 613 return ArgType::ObjCPointerTy; 614 default: 615 break; 616 } 617 618 // FIXME: Handle other cases. 619 return ArgType(); 620 } 621 622 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, 623 ASTContext &Ctx, bool IsObjCLiteral) { 624 // %n is different from other conversion specifiers; don't try to fix it. 625 if (CS.getKind() == ConversionSpecifier::nArg) 626 return false; 627 628 // Handle Objective-C objects first. Note that while the '%@' specifier will 629 // not warn for structure pointer or void pointer arguments (because that's 630 // how CoreFoundation objects are implemented), we only show a fixit for '%@' 631 // if we know it's an object (block, id, class, or __attribute__((NSObject))). 632 if (QT->isObjCRetainableType()) { 633 if (!IsObjCLiteral) 634 return false; 635 636 CS.setKind(ConversionSpecifier::ObjCObjArg); 637 638 // Disable irrelevant flags 639 HasThousandsGrouping = false; 640 HasPlusPrefix = false; 641 HasSpacePrefix = false; 642 HasAlternativeForm = false; 643 HasLeadingZeroes = false; 644 Precision.setHowSpecified(OptionalAmount::NotSpecified); 645 LM.setKind(LengthModifier::None); 646 647 return true; 648 } 649 650 // Handle strings next (char *, wchar_t *) 651 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 652 CS.setKind(ConversionSpecifier::sArg); 653 654 // Disable irrelevant flags 655 HasAlternativeForm = 0; 656 HasLeadingZeroes = 0; 657 658 // Set the long length modifier for wide characters 659 if (QT->getPointeeType()->isWideCharType()) 660 LM.setKind(LengthModifier::AsWideChar); 661 else 662 LM.setKind(LengthModifier::None); 663 664 return true; 665 } 666 667 // If it's an enum, get its underlying type. 668 if (const EnumType *ETy = QT->getAs<EnumType>()) 669 QT = ETy->getDecl()->getIntegerType(); 670 671 // We can only work with builtin types. 672 const BuiltinType *BT = QT->getAs<BuiltinType>(); 673 if (!BT) 674 return false; 675 676 // Set length modifier 677 switch (BT->getKind()) { 678 case BuiltinType::Bool: 679 case BuiltinType::WChar_U: 680 case BuiltinType::WChar_S: 681 case BuiltinType::Char8: // FIXME: Treat like 'char'? 682 case BuiltinType::Char16: 683 case BuiltinType::Char32: 684 case BuiltinType::UInt128: 685 case BuiltinType::Int128: 686 case BuiltinType::Half: 687 case BuiltinType::Float16: 688 case BuiltinType::Float128: 689 case BuiltinType::ShortAccum: 690 case BuiltinType::Accum: 691 case BuiltinType::LongAccum: 692 case BuiltinType::UShortAccum: 693 case BuiltinType::UAccum: 694 case BuiltinType::ULongAccum: 695 case BuiltinType::ShortFract: 696 case BuiltinType::Fract: 697 case BuiltinType::LongFract: 698 case BuiltinType::UShortFract: 699 case BuiltinType::UFract: 700 case BuiltinType::ULongFract: 701 case BuiltinType::SatShortAccum: 702 case BuiltinType::SatAccum: 703 case BuiltinType::SatLongAccum: 704 case BuiltinType::SatUShortAccum: 705 case BuiltinType::SatUAccum: 706 case BuiltinType::SatULongAccum: 707 case BuiltinType::SatShortFract: 708 case BuiltinType::SatFract: 709 case BuiltinType::SatLongFract: 710 case BuiltinType::SatUShortFract: 711 case BuiltinType::SatUFract: 712 case BuiltinType::SatULongFract: 713 // Various types which are non-trivial to correct. 714 return false; 715 716 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 717 case BuiltinType::Id: 718 #include "clang/Basic/OpenCLImageTypes.def" 719 #define SIGNED_TYPE(Id, SingletonId) 720 #define UNSIGNED_TYPE(Id, SingletonId) 721 #define FLOATING_TYPE(Id, SingletonId) 722 #define BUILTIN_TYPE(Id, SingletonId) \ 723 case BuiltinType::Id: 724 #include "clang/AST/BuiltinTypes.def" 725 // Misc other stuff which doesn't make sense here. 726 return false; 727 728 case BuiltinType::UInt: 729 case BuiltinType::Int: 730 case BuiltinType::Float: 731 case BuiltinType::Double: 732 LM.setKind(LengthModifier::None); 733 break; 734 735 case BuiltinType::Char_U: 736 case BuiltinType::UChar: 737 case BuiltinType::Char_S: 738 case BuiltinType::SChar: 739 LM.setKind(LengthModifier::AsChar); 740 break; 741 742 case BuiltinType::Short: 743 case BuiltinType::UShort: 744 LM.setKind(LengthModifier::AsShort); 745 break; 746 747 case BuiltinType::Long: 748 case BuiltinType::ULong: 749 LM.setKind(LengthModifier::AsLong); 750 break; 751 752 case BuiltinType::LongLong: 753 case BuiltinType::ULongLong: 754 LM.setKind(LengthModifier::AsLongLong); 755 break; 756 757 case BuiltinType::LongDouble: 758 LM.setKind(LengthModifier::AsLongDouble); 759 break; 760 } 761 762 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 763 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11)) 764 namedTypeToLengthModifier(QT, LM); 765 766 // If fixing the length modifier was enough, we might be done. 767 if (hasValidLengthModifier(Ctx.getTargetInfo())) { 768 // If we're going to offer a fix anyway, make sure the sign matches. 769 switch (CS.getKind()) { 770 case ConversionSpecifier::uArg: 771 case ConversionSpecifier::UArg: 772 if (QT->isSignedIntegerType()) 773 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg); 774 break; 775 case ConversionSpecifier::dArg: 776 case ConversionSpecifier::DArg: 777 case ConversionSpecifier::iArg: 778 if (QT->isUnsignedIntegerType() && !HasPlusPrefix) 779 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg); 780 break; 781 default: 782 // Other specifiers do not have signed/unsigned variants. 783 break; 784 } 785 786 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral); 787 if (ATR.isValid() && ATR.matchesType(Ctx, QT)) 788 return true; 789 } 790 791 // Set conversion specifier and disable any flags which do not apply to it. 792 // Let typedefs to char fall through to int, as %c is silly for uint8_t. 793 if (!isa<TypedefType>(QT) && QT->isCharType()) { 794 CS.setKind(ConversionSpecifier::cArg); 795 LM.setKind(LengthModifier::None); 796 Precision.setHowSpecified(OptionalAmount::NotSpecified); 797 HasAlternativeForm = 0; 798 HasLeadingZeroes = 0; 799 HasPlusPrefix = 0; 800 } 801 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 802 else if (QT->isRealFloatingType()) { 803 CS.setKind(ConversionSpecifier::fArg); 804 } 805 else if (QT->isSignedIntegerType()) { 806 CS.setKind(ConversionSpecifier::dArg); 807 HasAlternativeForm = 0; 808 } 809 else if (QT->isUnsignedIntegerType()) { 810 CS.setKind(ConversionSpecifier::uArg); 811 HasAlternativeForm = 0; 812 HasPlusPrefix = 0; 813 } else { 814 llvm_unreachable("Unexpected type"); 815 } 816 817 return true; 818 } 819 820 void PrintfSpecifier::toString(raw_ostream &os) const { 821 // Whilst some features have no defined order, we are using the order 822 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 823 os << "%"; 824 825 // Positional args 826 if (usesPositionalArg()) { 827 os << getPositionalArgIndex() << "$"; 828 } 829 830 // Conversion flags 831 if (IsLeftJustified) os << "-"; 832 if (HasPlusPrefix) os << "+"; 833 if (HasSpacePrefix) os << " "; 834 if (HasAlternativeForm) os << "#"; 835 if (HasLeadingZeroes) os << "0"; 836 837 // Minimum field width 838 FieldWidth.toString(os); 839 // Precision 840 Precision.toString(os); 841 // Length modifier 842 os << LM.toString(); 843 // Conversion specifier 844 os << CS.toString(); 845 } 846 847 bool PrintfSpecifier::hasValidPlusPrefix() const { 848 if (!HasPlusPrefix) 849 return true; 850 851 // The plus prefix only makes sense for signed conversions 852 switch (CS.getKind()) { 853 case ConversionSpecifier::dArg: 854 case ConversionSpecifier::DArg: 855 case ConversionSpecifier::iArg: 856 case ConversionSpecifier::fArg: 857 case ConversionSpecifier::FArg: 858 case ConversionSpecifier::eArg: 859 case ConversionSpecifier::EArg: 860 case ConversionSpecifier::gArg: 861 case ConversionSpecifier::GArg: 862 case ConversionSpecifier::aArg: 863 case ConversionSpecifier::AArg: 864 case ConversionSpecifier::FreeBSDrArg: 865 case ConversionSpecifier::FreeBSDyArg: 866 return true; 867 868 default: 869 return false; 870 } 871 } 872 873 bool PrintfSpecifier::hasValidAlternativeForm() const { 874 if (!HasAlternativeForm) 875 return true; 876 877 // Alternate form flag only valid with the oxXaAeEfFgG conversions 878 switch (CS.getKind()) { 879 case ConversionSpecifier::oArg: 880 case ConversionSpecifier::OArg: 881 case ConversionSpecifier::xArg: 882 case ConversionSpecifier::XArg: 883 case ConversionSpecifier::aArg: 884 case ConversionSpecifier::AArg: 885 case ConversionSpecifier::eArg: 886 case ConversionSpecifier::EArg: 887 case ConversionSpecifier::fArg: 888 case ConversionSpecifier::FArg: 889 case ConversionSpecifier::gArg: 890 case ConversionSpecifier::GArg: 891 case ConversionSpecifier::FreeBSDrArg: 892 case ConversionSpecifier::FreeBSDyArg: 893 return true; 894 895 default: 896 return false; 897 } 898 } 899 900 bool PrintfSpecifier::hasValidLeadingZeros() const { 901 if (!HasLeadingZeroes) 902 return true; 903 904 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 905 switch (CS.getKind()) { 906 case ConversionSpecifier::dArg: 907 case ConversionSpecifier::DArg: 908 case ConversionSpecifier::iArg: 909 case ConversionSpecifier::oArg: 910 case ConversionSpecifier::OArg: 911 case ConversionSpecifier::uArg: 912 case ConversionSpecifier::UArg: 913 case ConversionSpecifier::xArg: 914 case ConversionSpecifier::XArg: 915 case ConversionSpecifier::aArg: 916 case ConversionSpecifier::AArg: 917 case ConversionSpecifier::eArg: 918 case ConversionSpecifier::EArg: 919 case ConversionSpecifier::fArg: 920 case ConversionSpecifier::FArg: 921 case ConversionSpecifier::gArg: 922 case ConversionSpecifier::GArg: 923 case ConversionSpecifier::FreeBSDrArg: 924 case ConversionSpecifier::FreeBSDyArg: 925 return true; 926 927 default: 928 return false; 929 } 930 } 931 932 bool PrintfSpecifier::hasValidSpacePrefix() const { 933 if (!HasSpacePrefix) 934 return true; 935 936 // The space prefix only makes sense for signed conversions 937 switch (CS.getKind()) { 938 case ConversionSpecifier::dArg: 939 case ConversionSpecifier::DArg: 940 case ConversionSpecifier::iArg: 941 case ConversionSpecifier::fArg: 942 case ConversionSpecifier::FArg: 943 case ConversionSpecifier::eArg: 944 case ConversionSpecifier::EArg: 945 case ConversionSpecifier::gArg: 946 case ConversionSpecifier::GArg: 947 case ConversionSpecifier::aArg: 948 case ConversionSpecifier::AArg: 949 case ConversionSpecifier::FreeBSDrArg: 950 case ConversionSpecifier::FreeBSDyArg: 951 return true; 952 953 default: 954 return false; 955 } 956 } 957 958 bool PrintfSpecifier::hasValidLeftJustified() const { 959 if (!IsLeftJustified) 960 return true; 961 962 // The left justified flag is valid for all conversions except n 963 switch (CS.getKind()) { 964 case ConversionSpecifier::nArg: 965 return false; 966 967 default: 968 return true; 969 } 970 } 971 972 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 973 if (!HasThousandsGrouping) 974 return true; 975 976 switch (CS.getKind()) { 977 case ConversionSpecifier::dArg: 978 case ConversionSpecifier::DArg: 979 case ConversionSpecifier::iArg: 980 case ConversionSpecifier::uArg: 981 case ConversionSpecifier::UArg: 982 case ConversionSpecifier::fArg: 983 case ConversionSpecifier::FArg: 984 case ConversionSpecifier::gArg: 985 case ConversionSpecifier::GArg: 986 return true; 987 default: 988 return false; 989 } 990 } 991 992 bool PrintfSpecifier::hasValidPrecision() const { 993 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 994 return true; 995 996 // Precision is only valid with the diouxXaAeEfFgGsP conversions 997 switch (CS.getKind()) { 998 case ConversionSpecifier::dArg: 999 case ConversionSpecifier::DArg: 1000 case ConversionSpecifier::iArg: 1001 case ConversionSpecifier::oArg: 1002 case ConversionSpecifier::OArg: 1003 case ConversionSpecifier::uArg: 1004 case ConversionSpecifier::UArg: 1005 case ConversionSpecifier::xArg: 1006 case ConversionSpecifier::XArg: 1007 case ConversionSpecifier::aArg: 1008 case ConversionSpecifier::AArg: 1009 case ConversionSpecifier::eArg: 1010 case ConversionSpecifier::EArg: 1011 case ConversionSpecifier::fArg: 1012 case ConversionSpecifier::FArg: 1013 case ConversionSpecifier::gArg: 1014 case ConversionSpecifier::GArg: 1015 case ConversionSpecifier::sArg: 1016 case ConversionSpecifier::FreeBSDrArg: 1017 case ConversionSpecifier::FreeBSDyArg: 1018 case ConversionSpecifier::PArg: 1019 return true; 1020 1021 default: 1022 return false; 1023 } 1024 } 1025 bool PrintfSpecifier::hasValidFieldWidth() const { 1026 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 1027 return true; 1028 1029 // The field width is valid for all conversions except n 1030 switch (CS.getKind()) { 1031 case ConversionSpecifier::nArg: 1032 return false; 1033 1034 default: 1035 return true; 1036 } 1037 } 1038