diff options
author | Hans Wennborg <hans@hanshq.net> | 2011-12-15 10:25:47 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2011-12-15 10:25:47 +0000 |
commit | 23926bd2d78ca1898e8565039b6de06d329eeb9e (patch) | |
tree | 1f918189aff3cb758c6e432c89bf997e392a5f53 /clang/lib/Analysis/ScanfFormatString.cpp | |
parent | adba86d63c1d5c93cc559291499d63dbc19baeb5 (diff) | |
download | bcm5719-llvm-23926bd2d78ca1898e8565039b6de06d329eeb9e.tar.gz bcm5719-llvm-23926bd2d78ca1898e8565039b6de06d329eeb9e.zip |
Support the 'a' length modifier in scanf format strings as a C90
extension.
This fixes gcc.dg/format/c90-scanf-3.c and ext-4.c (test for excess
errors).
llvm-svn: 146649
Diffstat (limited to 'clang/lib/Analysis/ScanfFormatString.cpp')
-rw-r--r-- | clang/lib/Analysis/ScanfFormatString.cpp | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/clang/lib/Analysis/ScanfFormatString.cpp b/clang/lib/Analysis/ScanfFormatString.cpp index 77d9c9658d3..e8bd0d0e246 100644 --- a/clang/lib/Analysis/ScanfFormatString.cpp +++ b/clang/lib/Analysis/ScanfFormatString.cpp @@ -67,7 +67,8 @@ static bool ParseScanList(FormatStringHandler &H, static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, - unsigned &argIndex) { + unsigned &argIndex, + const LangOptions &LO) { using namespace clang::analyze_scanf; const char *I = Beg; @@ -132,7 +133,7 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, } // Look for the length modifier. - if (ParseLengthModifier(FS, I, E) && I == E) { + if (ParseLengthModifier(FS, I, E, LO, /*scanf=*/true) && I == E) { // No more characters left? H.HandleIncompleteSpecifier(Start, E - Start); return true; @@ -218,6 +219,7 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsPtrDiff: return ScanfArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t *"); case LengthModifier::AsLongDouble: return ScanfArgTypeResult::Invalid(); + case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid(); } // Unsigned int. @@ -240,6 +242,7 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const { // FIXME: Unsigned version of ptrdiff_t? return ScanfArgTypeResult(); case LengthModifier::AsLongDouble: return ScanfArgTypeResult::Invalid(); + case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid(); } // Float. @@ -274,7 +277,9 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const { case ConversionSpecifier::CArg: case ConversionSpecifier::SArg: // FIXME: Mac OS X specific? - return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *"); + if (LM.getKind() == LengthModifier::None) + return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *"); + return ScanfArgTypeResult::Invalid(); // Pointer. case ConversionSpecifier::pArg: @@ -401,13 +406,15 @@ void ScanfSpecifier::toString(raw_ostream &os) const { bool clang::analyze_format_string::ParseScanfString(FormatStringHandler &H, const char *I, - const char *E) { + const char *E, + const LangOptions &LO) { unsigned argIndex = 0; // Keep looking for a format specifier until we have exhausted the string. while (I != E) { - const ScanfSpecifierResult &FSR = ParseScanfSpecifier(H, I, E, argIndex); + const ScanfSpecifierResult &FSR = ParseScanfSpecifier(H, I, E, argIndex, + LO); // Did a fail-stop error of any kind occur when parsing the specifier? // If so, don't do any more processing. if (FSR.shouldStop()) |