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