From: Ted Kremenek Date: Thu, 28 Jan 2010 02:46:17 +0000 (+0000) Subject: Add position of conversion specifier character to 'ConversionSpecifier'. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a8d8fec7876666d90bb2a144d3b832b2d89a088a;p=clang Add position of conversion specifier character to 'ConversionSpecifier'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94739 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/Analyses/PrintfFormatString.h b/include/clang/Analysis/Analyses/PrintfFormatString.h index d8630e8edb..45d1055be6 100644 --- a/include/clang/Analysis/Analyses/PrintfFormatString.h +++ b/include/clang/Analysis/Analyses/PrintfFormatString.h @@ -59,7 +59,15 @@ public: ObjCEnd = ObjCObjArg }; - ConversionSpecifier(Kind k) : kind(k) {} + ConversionSpecifier() + : Position(0), kind(InvalidSpecifier) {} + + ConversionSpecifier(const char *pos, Kind k) + : Position(pos), kind(k) {} + + const char *getConversionStart() const { + return Position; + } bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; } bool isIntArg() const { return kind >= dArg && kind <= iArg; } @@ -68,7 +76,8 @@ public: Kind getKind() const { return kind; } private: - const Kind kind; + const char *Position; + Kind kind; }; enum LengthModifier { @@ -115,19 +124,19 @@ private: }; class FormatSpecifier { - unsigned conversionSpecifier : 6; unsigned lengthModifier : 5; unsigned flags : 5; + ConversionSpecifier conversionSpecifier; OptionalAmount FieldWidth; OptionalAmount Precision; public: - FormatSpecifier() : conversionSpecifier(0), lengthModifier(0), flags(0) {} + FormatSpecifier() : lengthModifier(0), flags(0) {} static FormatSpecifier Parse(const char *beg, const char *end); // Methods for incrementally constructing the FormatSpecifier. - void setConversionSpecifier(ConversionSpecifier cs) { - conversionSpecifier = (unsigned) cs.getKind(); + void setConversionSpecifier(const ConversionSpecifier &CS) { + conversionSpecifier = CS; } void setLengthModifier(LengthModifier lm) { lengthModifier = (unsigned) lm; @@ -140,8 +149,8 @@ public: // Methods for querying the format specifier. - ConversionSpecifier getConversionSpecifier() const { - return (ConversionSpecifier::Kind) conversionSpecifier; + const ConversionSpecifier &getConversionSpecifier() const { + return conversionSpecifier; } LengthModifier getLengthModifier() const { @@ -187,7 +196,9 @@ public: virtual bool HandleFormatSpecifier(const FormatSpecifier &FS, const char *startSpecifier, - const char *endSpecifier) { return false; } + unsigned specifierLen) { + return true; + } }; bool ParseFormatString(FormatStringHandler &H, diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp index 81752e9c4c..544956ac41 100644 --- a/lib/Analysis/PrintfFormatString.cpp +++ b/lib/Analysis/PrintfFormatString.cpp @@ -189,39 +189,42 @@ static FormatSpecifierResult ParseFormatSpecifier(FormatStringHandler &H, } // Finally, look for the conversion specifier. - ConversionSpecifier::Kind cs; - switch (*I) { + const char *conversionPosition = I++; + ConversionSpecifier::Kind k; + switch (*conversionPosition) { default: - H.HandleInvalidConversionSpecifier(I); + H.HandleInvalidConversionSpecifier(conversionPosition); return true; // C99: 7.19.6.1 (section 8). - case 'd': cs = ConversionSpecifier::dArg; break; - case 'i': cs = ConversionSpecifier::iArg; break; - case 'o': cs = ConversionSpecifier::oArg; break; - case 'u': cs = ConversionSpecifier::uArg; break; - case 'x': cs = ConversionSpecifier::xArg; break; - case 'X': cs = ConversionSpecifier::XArg; break; - case 'f': cs = ConversionSpecifier::fArg; break; - case 'F': cs = ConversionSpecifier::FArg; break; - case 'e': cs = ConversionSpecifier::eArg; break; - case 'E': cs = ConversionSpecifier::EArg; break; - case 'g': cs = ConversionSpecifier::gArg; break; - case 'G': cs = ConversionSpecifier::GArg; break; - case 'a': cs = ConversionSpecifier::aArg; break; - case 'A': cs = ConversionSpecifier::AArg; break; - case 'c': cs = ConversionSpecifier::IntAsCharArg; break; - case 's': cs = ConversionSpecifier::CStrArg; break; - case 'p': cs = ConversionSpecifier::VoidPtrArg; break; - case 'n': cs = ConversionSpecifier::OutIntPtrArg; break; - case '%': cs = ConversionSpecifier::PercentArg; break; + case 'd': k = ConversionSpecifier::dArg; break; + case 'i': k = ConversionSpecifier::iArg; break; + case 'o': k = ConversionSpecifier::oArg; break; + case 'u': k = ConversionSpecifier::uArg; break; + case 'x': k = ConversionSpecifier::xArg; break; + case 'X': k = ConversionSpecifier::XArg; break; + case 'f': k = ConversionSpecifier::fArg; break; + case 'F': k = ConversionSpecifier::FArg; break; + case 'e': k = ConversionSpecifier::eArg; break; + case 'E': k = ConversionSpecifier::EArg; break; + case 'g': k = ConversionSpecifier::gArg; break; + case 'G': k = ConversionSpecifier::GArg; break; + case 'a': k = ConversionSpecifier::aArg; break; + case 'A': k = ConversionSpecifier::AArg; break; + case 'c': k = ConversionSpecifier::IntAsCharArg; break; + case 's': k = ConversionSpecifier::CStrArg; break; + case 'p': k = ConversionSpecifier::VoidPtrArg; break; + case 'n': k = ConversionSpecifier::OutIntPtrArg; break; + case '%': k = ConversionSpecifier::PercentArg; break; // Objective-C. - case '@': cs = ConversionSpecifier::ObjCObjArg; break; + case '@': k = ConversionSpecifier::ObjCObjArg; break; } - FS.setConversionSpecifier(cs); + FS.setConversionSpecifier(ConversionSpecifier(conversionPosition, k)); return FormatSpecifierResult(Start, FS); } -bool ParseFormatSring(FormatStringHandler &H, const char *I, const char *E) { +namespace clang { namespace analyze_printf { +bool ParseFormatString(FormatStringHandler &H, + const char *I, const char *E) { // Keep looking for a format specifier until we have exhausted the string. while (I != E) { const FormatSpecifierResult &FSR = ParseFormatSpecifier(H, I, E); @@ -233,11 +236,13 @@ bool ParseFormatSring(FormatStringHandler &H, const char *I, const char *E) { if (!FSR.hasValue()) break; // We have a format specifier. Pass it to the callback. - if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(), I)) + if (!H.HandleFormatSpecifier(FSR.getValue(), FSR.getStart(), + I - FSR.getStart())) return false; } assert(I == E && "Format string not exhausted"); return false; } +}} FormatStringHandler::~FormatStringHandler() {}