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