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