summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/ScanfFormatString.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2011-12-15 10:25:47 +0000
committerHans Wennborg <hans@hanshq.net>2011-12-15 10:25:47 +0000
commit23926bd2d78ca1898e8565039b6de06d329eeb9e (patch)
tree1f918189aff3cb758c6e432c89bf997e392a5f53 /clang/lib/Analysis/ScanfFormatString.cpp
parentadba86d63c1d5c93cc559291499d63dbc19baeb5 (diff)
downloadbcm5719-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.cpp17
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())
OpenPOWER on IntegriCloud