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