PrintfFormatString.cpp revision 263508
1178825Sdfr//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 2233294Sstas// 3233294Sstas// The LLVM Compiler Infrastructure 4233294Sstas// 5178825Sdfr// This file is distributed under the University of Illinois Open Source 6233294Sstas// License. See LICENSE.TXT for details. 7233294Sstas// 8233294Sstas//===----------------------------------------------------------------------===// 9178825Sdfr// 10233294Sstas// Handling of format string in printf and friends. The structure of format 11233294Sstas// strings for fprintf() are described in C99 7.19.6.1. 12178825Sdfr// 13233294Sstas//===----------------------------------------------------------------------===// 14233294Sstas 15233294Sstas#include "clang/Analysis/Analyses/FormatString.h" 16178825Sdfr#include "FormatStringParsing.h" 17233294Sstas#include "clang/Basic/TargetInfo.h" 18233294Sstas 19233294Sstasusing clang::analyze_format_string::ArgType; 20178825Sdfrusing clang::analyze_format_string::FormatStringHandler; 21233294Sstasusing clang::analyze_format_string::LengthModifier; 22233294Sstasusing clang::analyze_format_string::OptionalAmount; 23233294Sstasusing clang::analyze_format_string::ConversionSpecifier; 24233294Sstasusing clang::analyze_printf::PrintfSpecifier; 25233294Sstas 26233294Sstasusing namespace clang; 27233294Sstas 28233294Sstastypedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 29233294Sstas PrintfSpecifierResult; 30233294Sstas 31233294Sstas//===----------------------------------------------------------------------===// 32178825Sdfr// Methods for parsing format strings. 33178825Sdfr//===----------------------------------------------------------------------===// 34178825Sdfr 35178825Sdfrusing analyze_format_string::ParseNonPositionAmount; 36178825Sdfr 37178825Sdfrstatic bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 38178825Sdfr const char *Start, const char *&Beg, const char *E, 39233294Sstas unsigned *argIndex) { 40178825Sdfr if (argIndex) { 41178825Sdfr FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 42178825Sdfr } else { 43178825Sdfr const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 44178825Sdfr analyze_format_string::PrecisionPos); 45178825Sdfr if (Amt.isInvalid()) 46178825Sdfr return true; 47178825Sdfr FS.setPrecision(Amt); 48178825Sdfr } 49178825Sdfr return false; 50178825Sdfr} 51178825Sdfr 52178825Sdfrstatic PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 53178825Sdfr const char *&Beg, 54178825Sdfr const char *E, 55178825Sdfr unsigned &argIndex, 56178825Sdfr const LangOptions &LO, 57178825Sdfr const TargetInfo &Target) { 58178825Sdfr 59178825Sdfr using namespace clang::analyze_format_string; 60178825Sdfr using namespace clang::analyze_printf; 61178825Sdfr 62178825Sdfr const char *I = Beg; 63178825Sdfr const char *Start = 0; 64178825Sdfr UpdateOnReturn <const char*> UpdateBeg(Beg, I); 65178825Sdfr 66178825Sdfr // Look for a '%' character that indicates the start of a format specifier. 67178825Sdfr for ( ; I != E ; ++I) { 68178825Sdfr char c = *I; 69178825Sdfr if (c == '\0') { 70178825Sdfr // Detect spurious null characters, which are likely errors. 71178825Sdfr H.HandleNullChar(I); 72178825Sdfr return true; 73178825Sdfr } 74178825Sdfr if (c == '%') { 75178825Sdfr Start = I++; // Record the start of the format specifier. 76178825Sdfr break; 77178825Sdfr } 78233294Sstas } 79178825Sdfr 80178825Sdfr // No format specifier found? 81178825Sdfr if (!Start) 82178825Sdfr return false; 83178825Sdfr 84178825Sdfr if (I == E) { 85178825Sdfr // No more characters left? 86178825Sdfr H.HandleIncompleteSpecifier(Start, E - Start); 87178825Sdfr return true; 88178825Sdfr } 89178825Sdfr 90178825Sdfr PrintfSpecifier FS; 91178825Sdfr if (ParseArgPosition(H, FS, Start, I, E)) 92178825Sdfr return true; 93178825Sdfr 94178825Sdfr if (I == E) { 95178825Sdfr // No more characters left? 96178825Sdfr H.HandleIncompleteSpecifier(Start, E - Start); 97178825Sdfr return true; 98178825Sdfr } 99178825Sdfr 100178825Sdfr // Look for flags (if any). 101178825Sdfr bool hasMore = true; 102178825Sdfr for ( ; I != E; ++I) { 103178825Sdfr switch (*I) { 104178825Sdfr default: hasMore = false; break; 105178825Sdfr case '\'': 106178825Sdfr // FIXME: POSIX specific. Always accept? 107178825Sdfr FS.setHasThousandsGrouping(I); 108178825Sdfr break; 109178825Sdfr case '-': FS.setIsLeftJustified(I); break; 110178825Sdfr case '+': FS.setHasPlusPrefix(I); break; 111178825Sdfr case ' ': FS.setHasSpacePrefix(I); break; 112178825Sdfr case '#': FS.setHasAlternativeForm(I); break; 113178825Sdfr case '0': FS.setHasLeadingZeros(I); break; 114178825Sdfr } 115178825Sdfr if (!hasMore) 116178825Sdfr break; 117178825Sdfr } 118178825Sdfr 119178825Sdfr if (I == E) { 120178825Sdfr // No more characters left? 121178825Sdfr H.HandleIncompleteSpecifier(Start, E - Start); 122233294Sstas return true; 123178825Sdfr } 124178825Sdfr 125178825Sdfr // Look for the field width (if any). 126178825Sdfr if (ParseFieldWidth(H, FS, Start, I, E, 127233294Sstas FS.usesPositionalArg() ? 0 : &argIndex)) 128178825Sdfr return true; 129178825Sdfr 130178825Sdfr if (I == E) { 131178825Sdfr // No more characters left? 132178825Sdfr H.HandleIncompleteSpecifier(Start, E - Start); 133178825Sdfr return true; 134178825Sdfr } 135178825Sdfr 136178825Sdfr // Look for the precision (if any). 137178825Sdfr if (*I == '.') { 138178825Sdfr ++I; 139178825Sdfr if (I == E) { 140178825Sdfr H.HandleIncompleteSpecifier(Start, E - Start); 141178825Sdfr return true; 142178825Sdfr } 143178825Sdfr 144178825Sdfr if (ParsePrecision(H, FS, Start, I, E, 145178825Sdfr FS.usesPositionalArg() ? 0 : &argIndex)) 146178825Sdfr return true; 147178825Sdfr 148178825Sdfr if (I == E) { 149178825Sdfr // No more characters left? 150178825Sdfr H.HandleIncompleteSpecifier(Start, E - Start); 151178825Sdfr return true; 152178825Sdfr } 153178825Sdfr } 154178825Sdfr 155178825Sdfr // Look for the length modifier. 156178825Sdfr if (ParseLengthModifier(FS, I, E, LO) && I == E) { 157178825Sdfr // No more characters left? 158178825Sdfr H.HandleIncompleteSpecifier(Start, E - Start); 159178825Sdfr return true; 160178825Sdfr } 161178825Sdfr 162178825Sdfr if (*I == '\0') { 163178825Sdfr // Detect spurious null characters, which are likely errors. 164178825Sdfr H.HandleNullChar(I); 165178825Sdfr return true; 166178825Sdfr } 167178825Sdfr 168178825Sdfr // Finally, look for the conversion specifier. 169178825Sdfr const char *conversionPosition = I++; 170178825Sdfr ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 171178825Sdfr switch (*conversionPosition) { 172178825Sdfr default: 173178825Sdfr break; 174178825Sdfr // C99: 7.19.6.1 (section 8). 175178825Sdfr case '%': k = ConversionSpecifier::PercentArg; break; 176178825Sdfr case 'A': k = ConversionSpecifier::AArg; break; 177178825Sdfr case 'E': k = ConversionSpecifier::EArg; break; 178178825Sdfr case 'F': k = ConversionSpecifier::FArg; break; 179178825Sdfr case 'G': k = ConversionSpecifier::GArg; break; 180178825Sdfr case 'X': k = ConversionSpecifier::XArg; break; 181178825Sdfr case 'a': k = ConversionSpecifier::aArg; break; 182178825Sdfr case 'c': k = ConversionSpecifier::cArg; break; 183178825Sdfr case 'd': k = ConversionSpecifier::dArg; break; 184178825Sdfr case 'e': k = ConversionSpecifier::eArg; break; 185178825Sdfr case 'f': k = ConversionSpecifier::fArg; break; 186178825Sdfr case 'g': k = ConversionSpecifier::gArg; break; 187233294Sstas case 'i': k = ConversionSpecifier::iArg; break; 188178825Sdfr case 'n': k = ConversionSpecifier::nArg; break; 189178825Sdfr case 'o': k = ConversionSpecifier::oArg; break; 190178825Sdfr case 'p': k = ConversionSpecifier::pArg; break; 191178825Sdfr case 's': k = ConversionSpecifier::sArg; break; 192178825Sdfr case 'u': k = ConversionSpecifier::uArg; break; 193178825Sdfr case 'x': k = ConversionSpecifier::xArg; break; 194178825Sdfr // POSIX specific. 195178825Sdfr case 'C': k = ConversionSpecifier::CArg; break; 196233294Sstas case 'S': k = ConversionSpecifier::SArg; break; 197178825Sdfr // Objective-C. 198178825Sdfr case '@': k = ConversionSpecifier::ObjCObjArg; break; 199178825Sdfr // Glibc specific. 200178825Sdfr case 'm': k = ConversionSpecifier::PrintErrno; break; 201178825Sdfr // FreeBSD format extensions 202178825Sdfr case 'b': 203178825Sdfr if (LO.FormatExtensions) 204233294Sstas k = ConversionSpecifier::FreeBSDbArg; // int followed by char * 205178825Sdfr break; 206178825Sdfr case 'r': 207178825Sdfr if (LO.FormatExtensions) 208178825Sdfr k = ConversionSpecifier::FreeBSDrArg; 209178825Sdfr break; 210178825Sdfr case 'y': 211178825Sdfr if (LO.FormatExtensions) 212178825Sdfr k = ConversionSpecifier::iArg; 213178825Sdfr break; 214178825Sdfr // Apple-specific 215178825Sdfr case 'D': 216178825Sdfr if (Target.getTriple().isOSDarwin()) 217178825Sdfr k = ConversionSpecifier::DArg; 218178825Sdfr else if (LO.FormatExtensions) 219178825Sdfr k = ConversionSpecifier::FreeBSDDArg; // u_char * followed by char * 220178825Sdfr break; 221178825Sdfr case 'O': 222178825Sdfr if (Target.getTriple().isOSDarwin()) 223178825Sdfr k = ConversionSpecifier::OArg; 224178825Sdfr break; 225178825Sdfr case 'U': 226178825Sdfr if (Target.getTriple().isOSDarwin()) 227178825Sdfr k = ConversionSpecifier::UArg; 228178825Sdfr break; 229178825Sdfr } 230178825Sdfr PrintfConversionSpecifier CS(conversionPosition, k); 231178825Sdfr FS.setConversionSpecifier(CS); 232178825Sdfr if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 233178825Sdfr FS.setArgIndex(argIndex++); 234178825Sdfr // FreeBSD extension 235178825Sdfr if (k == ConversionSpecifier::FreeBSDbArg || 236178825Sdfr k == ConversionSpecifier::FreeBSDDArg) 237178825Sdfr argIndex++; 238178825Sdfr 239178825Sdfr if (k == ConversionSpecifier::InvalidSpecifier) { 240178825Sdfr // Assume the conversion takes one argument. 241178825Sdfr return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 242178825Sdfr } 243178825Sdfr return PrintfSpecifierResult(Start, FS); 244178825Sdfr} 245178825Sdfr 246178825Sdfrbool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 247178825Sdfr const char *I, 248178825Sdfr const char *E, 249178825Sdfr const LangOptions &LO, 250178825Sdfr const TargetInfo &Target) { 251178825Sdfr 252178825Sdfr unsigned argIndex = 0; 253178825Sdfr 254178825Sdfr // Keep looking for a format specifier until we have exhausted the string. 255178825Sdfr while (I != E) { 256178825Sdfr const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 257178825Sdfr LO, Target); 258178825Sdfr // Did a fail-stop error of any kind occur when parsing the specifier? 259178825Sdfr // If so, don't do any more processing. 260178825Sdfr if (FSR.shouldStop()) 261178825Sdfr return true; 262178825Sdfr // Did we exhaust the string or encounter an error that 263178825Sdfr // we can recover from? 264178825Sdfr if (!FSR.hasValue()) 265178825Sdfr continue; 266178825Sdfr // We have a format specifier. Pass it to the callback. 267178825Sdfr if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 268178825Sdfr I - FSR.getStart())) 269178825Sdfr return true; 270178825Sdfr } 271178825Sdfr assert(I == E && "Format string not exhausted"); 272178825Sdfr return false; 273178825Sdfr} 274233294Sstas 275178825Sdfr//===----------------------------------------------------------------------===// 276178825Sdfr// Methods on PrintfSpecifier. 277178825Sdfr//===----------------------------------------------------------------------===// 278178825Sdfr 279178825SdfrArgType PrintfSpecifier::getArgType(ASTContext &Ctx, 280178825Sdfr bool IsObjCLiteral) const { 281178825Sdfr const PrintfConversionSpecifier &CS = getConversionSpecifier(); 282178825Sdfr 283178825Sdfr if (!CS.consumesDataArgument()) 284178825Sdfr return ArgType::Invalid(); 285178825Sdfr 286178825Sdfr if (CS.getKind() == ConversionSpecifier::cArg) 287178825Sdfr switch (LM.getKind()) { 288178825Sdfr case LengthModifier::None: return Ctx.IntTy; 289178825Sdfr case LengthModifier::AsLong: 290178825Sdfr return ArgType(ArgType::WIntTy, "wint_t"); 291178825Sdfr default: 292178825Sdfr return ArgType::Invalid(); 293178825Sdfr } 294178825Sdfr 295178825Sdfr if (CS.isIntArg()) 296178825Sdfr switch (LM.getKind()) { 297233294Sstas case LengthModifier::AsLongDouble: 298178825Sdfr // GNU extension. 299178825Sdfr return Ctx.LongLongTy; 300178825Sdfr case LengthModifier::None: 301178825Sdfr return Ctx.IntTy; 302178825Sdfr case LengthModifier::AsInt32: 303178825Sdfr return ArgType(Ctx.IntTy, "__int32"); 304178825Sdfr case LengthModifier::AsChar: return ArgType::AnyCharTy; 305178825Sdfr case LengthModifier::AsShort: return Ctx.ShortTy; 306178825Sdfr case LengthModifier::AsLong: return Ctx.LongTy; 307178825Sdfr case LengthModifier::AsLongLong: 308178825Sdfr case LengthModifier::AsQuad: 309178825Sdfr return Ctx.LongLongTy; 310178825Sdfr case LengthModifier::AsInt64: 311178825Sdfr return ArgType(Ctx.LongLongTy, "__int64"); 312178825Sdfr case LengthModifier::AsIntMax: 313178825Sdfr return ArgType(Ctx.getIntMaxType(), "intmax_t"); 314233294Sstas case LengthModifier::AsSizeT: 315178825Sdfr // FIXME: How to get the corresponding signed version of size_t? 316178825Sdfr return ArgType(); 317178825Sdfr case LengthModifier::AsInt3264: 318178825Sdfr return Ctx.getTargetInfo().getTriple().isArch64Bit() 319178825Sdfr ? ArgType(Ctx.LongLongTy, "__int64") 320178825Sdfr : ArgType(Ctx.IntTy, "__int32"); 321178825Sdfr case LengthModifier::AsPtrDiff: 322178825Sdfr return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"); 323178825Sdfr case LengthModifier::AsAllocate: 324178825Sdfr case LengthModifier::AsMAllocate: 325178825Sdfr return ArgType::Invalid(); 326178825Sdfr } 327178825Sdfr 328178825Sdfr if (CS.isUIntArg()) 329178825Sdfr switch (LM.getKind()) { 330178825Sdfr case LengthModifier::AsLongDouble: 331178825Sdfr // GNU extension. 332178825Sdfr return Ctx.UnsignedLongLongTy; 333178825Sdfr case LengthModifier::None: 334178825Sdfr return Ctx.UnsignedIntTy; 335178825Sdfr case LengthModifier::AsInt32: 336178825Sdfr return ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 337178825Sdfr case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 338178825Sdfr case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 339178825Sdfr case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 340178825Sdfr case LengthModifier::AsLongLong: 341178825Sdfr case LengthModifier::AsQuad: 342178825Sdfr return Ctx.UnsignedLongLongTy; 343178825Sdfr case LengthModifier::AsInt64: 344178825Sdfr return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64"); 345178825Sdfr case LengthModifier::AsIntMax: 346178825Sdfr return ArgType(Ctx.getUIntMaxType(), "uintmax_t"); 347233294Sstas case LengthModifier::AsSizeT: 348178825Sdfr return ArgType(Ctx.getSizeType(), "size_t"); 349178825Sdfr case LengthModifier::AsInt3264: 350178825Sdfr return Ctx.getTargetInfo().getTriple().isArch64Bit() 351178825Sdfr ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64") 352178825Sdfr : ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); 353233294Sstas case LengthModifier::AsPtrDiff: 354233294Sstas // FIXME: How to get the corresponding unsigned 355178825Sdfr // version of ptrdiff_t? 356178825Sdfr return ArgType(); 357178825Sdfr case LengthModifier::AsAllocate: 358178825Sdfr case LengthModifier::AsMAllocate: 359178825Sdfr return ArgType::Invalid(); 360178825Sdfr } 361178825Sdfr 362178825Sdfr if (CS.isDoubleArg()) { 363178825Sdfr if (LM.getKind() == LengthModifier::AsLongDouble) 364178825Sdfr return Ctx.LongDoubleTy; 365178825Sdfr return Ctx.DoubleTy; 366233294Sstas } 367178825Sdfr 368178825Sdfr if (CS.getKind() == ConversionSpecifier::nArg) { 369178825Sdfr switch (LM.getKind()) { 370178825Sdfr case LengthModifier::None: 371178825Sdfr return ArgType::PtrTo(Ctx.IntTy); 372178825Sdfr case LengthModifier::AsChar: 373178825Sdfr return ArgType::PtrTo(Ctx.SignedCharTy); 374178825Sdfr case LengthModifier::AsShort: 375178825Sdfr return ArgType::PtrTo(Ctx.ShortTy); 376233294Sstas case LengthModifier::AsLong: 377178825Sdfr return ArgType::PtrTo(Ctx.LongTy); 378178825Sdfr case LengthModifier::AsLongLong: 379178825Sdfr case LengthModifier::AsQuad: 380178825Sdfr return ArgType::PtrTo(Ctx.LongLongTy); 381178825Sdfr case LengthModifier::AsIntMax: 382178825Sdfr return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t")); 383178825Sdfr case LengthModifier::AsSizeT: 384178825Sdfr return ArgType(); // FIXME: ssize_t 385178825Sdfr case LengthModifier::AsPtrDiff: 386178825Sdfr return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")); 387178825Sdfr case LengthModifier::AsLongDouble: 388178825Sdfr return ArgType(); // FIXME: Is this a known extension? 389178825Sdfr case LengthModifier::AsAllocate: 390178825Sdfr case LengthModifier::AsMAllocate: 391178825Sdfr case LengthModifier::AsInt32: 392178825Sdfr case LengthModifier::AsInt3264: 393178825Sdfr case LengthModifier::AsInt64: 394178825Sdfr return ArgType::Invalid(); 395178825Sdfr } 396178825Sdfr } 397178825Sdfr 398178825Sdfr switch (CS.getKind()) { 399178825Sdfr case ConversionSpecifier::sArg: 400178825Sdfr if (LM.getKind() == LengthModifier::AsWideChar) { 401178825Sdfr if (IsObjCLiteral) 402178825Sdfr return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 403178825Sdfr "const unichar *"); 404178825Sdfr return ArgType(ArgType::WCStrTy, "wchar_t *"); 405178825Sdfr } 406178825Sdfr return ArgType::CStrTy; 407233294Sstas case ConversionSpecifier::SArg: 408233294Sstas if (IsObjCLiteral) 409233294Sstas return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), 410178825Sdfr "const unichar *"); 411178825Sdfr return ArgType(ArgType::WCStrTy, "wchar_t *"); 412178825Sdfr case ConversionSpecifier::CArg: 413178825Sdfr if (IsObjCLiteral) 414178825Sdfr return ArgType(Ctx.UnsignedShortTy, "unichar"); 415178825Sdfr return ArgType(Ctx.WideCharTy, "wchar_t"); 416178825Sdfr case ConversionSpecifier::pArg: 417178825Sdfr return ArgType::CPointerTy; 418178825Sdfr case ConversionSpecifier::ObjCObjArg: 419178825Sdfr return ArgType::ObjCPointerTy; 420178825Sdfr default: 421178825Sdfr break; 422178825Sdfr } 423178825Sdfr 424178825Sdfr // FIXME: Handle other cases. 425178825Sdfr return ArgType(); 426178825Sdfr} 427178825Sdfr 428178825Sdfrbool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, 429233294Sstas ASTContext &Ctx, bool IsObjCLiteral) { 430233294Sstas // %n is different from other conversion specifiers; don't try to fix it. 431178825Sdfr if (CS.getKind() == ConversionSpecifier::nArg) 432233294Sstas return false; 433233294Sstas 434178825Sdfr // Handle Objective-C objects first. Note that while the '%@' specifier will 435178825Sdfr // not warn for structure pointer or void pointer arguments (because that's 436178825Sdfr // how CoreFoundation objects are implemented), we only show a fixit for '%@' 437178825Sdfr // if we know it's an object (block, id, class, or __attribute__((NSObject))). 438178825Sdfr if (QT->isObjCRetainableType()) { 439178825Sdfr if (!IsObjCLiteral) 440178825Sdfr return false; 441178825Sdfr 442178825Sdfr CS.setKind(ConversionSpecifier::ObjCObjArg); 443178825Sdfr 444178825Sdfr // Disable irrelevant flags 445178825Sdfr HasThousandsGrouping = false; 446178825Sdfr HasPlusPrefix = false; 447178825Sdfr HasSpacePrefix = false; 448178825Sdfr HasAlternativeForm = false; 449178825Sdfr HasLeadingZeroes = false; 450178825Sdfr Precision.setHowSpecified(OptionalAmount::NotSpecified); 451178825Sdfr LM.setKind(LengthModifier::None); 452178825Sdfr 453178825Sdfr return true; 454178825Sdfr } 455178825Sdfr 456178825Sdfr // Handle strings next (char *, wchar_t *) 457178825Sdfr if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 458178825Sdfr CS.setKind(ConversionSpecifier::sArg); 459178825Sdfr 460178825Sdfr // Disable irrelevant flags 461178825Sdfr HasAlternativeForm = 0; 462178825Sdfr HasLeadingZeroes = 0; 463178825Sdfr 464178825Sdfr // Set the long length modifier for wide characters 465178825Sdfr if (QT->getPointeeType()->isWideCharType()) 466178825Sdfr LM.setKind(LengthModifier::AsWideChar); 467178825Sdfr else 468178825Sdfr LM.setKind(LengthModifier::None); 469178825Sdfr 470178825Sdfr return true; 471178825Sdfr } 472178825Sdfr 473178825Sdfr // If it's an enum, get its underlying type. 474178825Sdfr if (const EnumType *ETy = QT->getAs<EnumType>()) 475178825Sdfr QT = ETy->getDecl()->getIntegerType(); 476178825Sdfr 477178825Sdfr // We can only work with builtin types. 478178825Sdfr const BuiltinType *BT = QT->getAs<BuiltinType>(); 479178825Sdfr if (!BT) 480178825Sdfr return false; 481178825Sdfr 482178825Sdfr // Set length modifier 483178825Sdfr switch (BT->getKind()) { 484178825Sdfr case BuiltinType::Bool: 485178825Sdfr case BuiltinType::WChar_U: 486178825Sdfr case BuiltinType::WChar_S: 487178825Sdfr case BuiltinType::Char16: 488178825Sdfr case BuiltinType::Char32: 489178825Sdfr case BuiltinType::UInt128: 490 case BuiltinType::Int128: 491 case BuiltinType::Half: 492 // Various types which are non-trivial to correct. 493 return false; 494 495#define SIGNED_TYPE(Id, SingletonId) 496#define UNSIGNED_TYPE(Id, SingletonId) 497#define FLOATING_TYPE(Id, SingletonId) 498#define BUILTIN_TYPE(Id, SingletonId) \ 499 case BuiltinType::Id: 500#include "clang/AST/BuiltinTypes.def" 501 // Misc other stuff which doesn't make sense here. 502 return false; 503 504 case BuiltinType::UInt: 505 case BuiltinType::Int: 506 case BuiltinType::Float: 507 case BuiltinType::Double: 508 LM.setKind(LengthModifier::None); 509 break; 510 511 case BuiltinType::Char_U: 512 case BuiltinType::UChar: 513 case BuiltinType::Char_S: 514 case BuiltinType::SChar: 515 LM.setKind(LengthModifier::AsChar); 516 break; 517 518 case BuiltinType::Short: 519 case BuiltinType::UShort: 520 LM.setKind(LengthModifier::AsShort); 521 break; 522 523 case BuiltinType::Long: 524 case BuiltinType::ULong: 525 LM.setKind(LengthModifier::AsLong); 526 break; 527 528 case BuiltinType::LongLong: 529 case BuiltinType::ULongLong: 530 LM.setKind(LengthModifier::AsLongLong); 531 break; 532 533 case BuiltinType::LongDouble: 534 LM.setKind(LengthModifier::AsLongDouble); 535 break; 536 } 537 538 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 539 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11)) 540 namedTypeToLengthModifier(QT, LM); 541 542 // If fixing the length modifier was enough, we might be done. 543 if (hasValidLengthModifier(Ctx.getTargetInfo())) { 544 // If we're going to offer a fix anyway, make sure the sign matches. 545 switch (CS.getKind()) { 546 case ConversionSpecifier::uArg: 547 case ConversionSpecifier::UArg: 548 if (QT->isSignedIntegerType()) 549 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg); 550 break; 551 case ConversionSpecifier::dArg: 552 case ConversionSpecifier::DArg: 553 case ConversionSpecifier::iArg: 554 if (QT->isUnsignedIntegerType() && !HasPlusPrefix) 555 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg); 556 break; 557 default: 558 // Other specifiers do not have signed/unsigned variants. 559 break; 560 } 561 562 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral); 563 if (ATR.isValid() && ATR.matchesType(Ctx, QT)) 564 return true; 565 } 566 567 // Set conversion specifier and disable any flags which do not apply to it. 568 // Let typedefs to char fall through to int, as %c is silly for uint8_t. 569 if (!isa<TypedefType>(QT) && QT->isCharType()) { 570 CS.setKind(ConversionSpecifier::cArg); 571 LM.setKind(LengthModifier::None); 572 Precision.setHowSpecified(OptionalAmount::NotSpecified); 573 HasAlternativeForm = 0; 574 HasLeadingZeroes = 0; 575 HasPlusPrefix = 0; 576 } 577 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 578 else if (QT->isRealFloatingType()) { 579 CS.setKind(ConversionSpecifier::fArg); 580 } 581 else if (QT->isSignedIntegerType()) { 582 CS.setKind(ConversionSpecifier::dArg); 583 HasAlternativeForm = 0; 584 } 585 else if (QT->isUnsignedIntegerType()) { 586 CS.setKind(ConversionSpecifier::uArg); 587 HasAlternativeForm = 0; 588 HasPlusPrefix = 0; 589 } else { 590 llvm_unreachable("Unexpected type"); 591 } 592 593 return true; 594} 595 596void PrintfSpecifier::toString(raw_ostream &os) const { 597 // Whilst some features have no defined order, we are using the order 598 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 599 os << "%"; 600 601 // Positional args 602 if (usesPositionalArg()) { 603 os << getPositionalArgIndex() << "$"; 604 } 605 606 // Conversion flags 607 if (IsLeftJustified) os << "-"; 608 if (HasPlusPrefix) os << "+"; 609 if (HasSpacePrefix) os << " "; 610 if (HasAlternativeForm) os << "#"; 611 if (HasLeadingZeroes) os << "0"; 612 613 // Minimum field width 614 FieldWidth.toString(os); 615 // Precision 616 Precision.toString(os); 617 // Length modifier 618 os << LM.toString(); 619 // Conversion specifier 620 os << CS.toString(); 621} 622 623bool PrintfSpecifier::hasValidPlusPrefix() const { 624 if (!HasPlusPrefix) 625 return true; 626 627 // The plus prefix only makes sense for signed conversions 628 switch (CS.getKind()) { 629 case ConversionSpecifier::dArg: 630 case ConversionSpecifier::DArg: 631 case ConversionSpecifier::iArg: 632 case ConversionSpecifier::fArg: 633 case ConversionSpecifier::FArg: 634 case ConversionSpecifier::eArg: 635 case ConversionSpecifier::EArg: 636 case ConversionSpecifier::gArg: 637 case ConversionSpecifier::GArg: 638 case ConversionSpecifier::aArg: 639 case ConversionSpecifier::AArg: 640 case ConversionSpecifier::FreeBSDrArg: 641 return true; 642 643 default: 644 return false; 645 } 646} 647 648bool PrintfSpecifier::hasValidAlternativeForm() const { 649 if (!HasAlternativeForm) 650 return true; 651 652 // Alternate form flag only valid with the oxXaAeEfFgG conversions 653 switch (CS.getKind()) { 654 case ConversionSpecifier::oArg: 655 case ConversionSpecifier::OArg: 656 case ConversionSpecifier::xArg: 657 case ConversionSpecifier::XArg: 658 case ConversionSpecifier::aArg: 659 case ConversionSpecifier::AArg: 660 case ConversionSpecifier::eArg: 661 case ConversionSpecifier::EArg: 662 case ConversionSpecifier::fArg: 663 case ConversionSpecifier::FArg: 664 case ConversionSpecifier::gArg: 665 case ConversionSpecifier::GArg: 666 case ConversionSpecifier::FreeBSDrArg: 667 return true; 668 669 default: 670 return false; 671 } 672} 673 674bool PrintfSpecifier::hasValidLeadingZeros() const { 675 if (!HasLeadingZeroes) 676 return true; 677 678 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 679 switch (CS.getKind()) { 680 case ConversionSpecifier::dArg: 681 case ConversionSpecifier::DArg: 682 case ConversionSpecifier::iArg: 683 case ConversionSpecifier::oArg: 684 case ConversionSpecifier::OArg: 685 case ConversionSpecifier::uArg: 686 case ConversionSpecifier::UArg: 687 case ConversionSpecifier::xArg: 688 case ConversionSpecifier::XArg: 689 case ConversionSpecifier::aArg: 690 case ConversionSpecifier::AArg: 691 case ConversionSpecifier::eArg: 692 case ConversionSpecifier::EArg: 693 case ConversionSpecifier::fArg: 694 case ConversionSpecifier::FArg: 695 case ConversionSpecifier::gArg: 696 case ConversionSpecifier::GArg: 697 return true; 698 699 default: 700 return false; 701 } 702} 703 704bool PrintfSpecifier::hasValidSpacePrefix() const { 705 if (!HasSpacePrefix) 706 return true; 707 708 // The space prefix only makes sense for signed conversions 709 switch (CS.getKind()) { 710 case ConversionSpecifier::dArg: 711 case ConversionSpecifier::DArg: 712 case ConversionSpecifier::iArg: 713 case ConversionSpecifier::fArg: 714 case ConversionSpecifier::FArg: 715 case ConversionSpecifier::eArg: 716 case ConversionSpecifier::EArg: 717 case ConversionSpecifier::gArg: 718 case ConversionSpecifier::GArg: 719 case ConversionSpecifier::aArg: 720 case ConversionSpecifier::AArg: 721 return true; 722 723 default: 724 return false; 725 } 726} 727 728bool PrintfSpecifier::hasValidLeftJustified() const { 729 if (!IsLeftJustified) 730 return true; 731 732 // The left justified flag is valid for all conversions except n 733 switch (CS.getKind()) { 734 case ConversionSpecifier::nArg: 735 return false; 736 737 default: 738 return true; 739 } 740} 741 742bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 743 if (!HasThousandsGrouping) 744 return true; 745 746 switch (CS.getKind()) { 747 case ConversionSpecifier::dArg: 748 case ConversionSpecifier::DArg: 749 case ConversionSpecifier::iArg: 750 case ConversionSpecifier::uArg: 751 case ConversionSpecifier::UArg: 752 case ConversionSpecifier::fArg: 753 case ConversionSpecifier::FArg: 754 case ConversionSpecifier::gArg: 755 case ConversionSpecifier::GArg: 756 return true; 757 default: 758 return false; 759 } 760} 761 762bool PrintfSpecifier::hasValidPrecision() const { 763 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 764 return true; 765 766 // Precision is only valid with the diouxXaAeEfFgGs conversions 767 switch (CS.getKind()) { 768 case ConversionSpecifier::dArg: 769 case ConversionSpecifier::DArg: 770 case ConversionSpecifier::iArg: 771 case ConversionSpecifier::oArg: 772 case ConversionSpecifier::OArg: 773 case ConversionSpecifier::uArg: 774 case ConversionSpecifier::UArg: 775 case ConversionSpecifier::xArg: 776 case ConversionSpecifier::XArg: 777 case ConversionSpecifier::aArg: 778 case ConversionSpecifier::AArg: 779 case ConversionSpecifier::eArg: 780 case ConversionSpecifier::EArg: 781 case ConversionSpecifier::fArg: 782 case ConversionSpecifier::FArg: 783 case ConversionSpecifier::gArg: 784 case ConversionSpecifier::GArg: 785 case ConversionSpecifier::sArg: 786 return true; 787 788 default: 789 return false; 790 } 791} 792bool PrintfSpecifier::hasValidFieldWidth() const { 793 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 794 return true; 795 796 // The field width is valid for all conversions except n 797 switch (CS.getKind()) { 798 case ConversionSpecifier::nArg: 799 return false; 800 801 default: 802 return true; 803 } 804} 805