diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-05-13 16:06:05 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-05-13 16:06:05 +0000 |
commit | 4554f9b134307c7aa44686ce6982a0af5a9fc0f2 (patch) | |
tree | cdb0403dcaaef00fbb234618519c19ca8ca8ff0e /clang/lib/Sema/SemaChecking.cpp | |
parent | 4a71ae268b930316a907b2ce0effe092faa87720 (diff) | |
download | bcm5719-llvm-4554f9b134307c7aa44686ce6982a0af5a9fc0f2.tar.gz bcm5719-llvm-4554f9b134307c7aa44686ce6982a0af5a9fc0f2.zip |
Fix <rdar://problem/6880975> [format string] Assertion failed: (Arg < NumArgs && "Arg access out of range!").
For format string checking, only check the type of the format
specifier for non-vararg functions.
llvm-svn: 71672
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 52 |
1 files changed, 27 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 67d9a1acbf6..22dcc49b554 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -917,36 +917,38 @@ void Sema::CheckPrintfString(const StringLiteral *FExpr, case '*': { ++numConversions; - if (!HasVAListArg && numConversions > numDataArgs) { + if (!HasVAListArg) { + if (numConversions > numDataArgs) { + SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, StrIdx); + + if (Str[StrIdx-1] == '.') + Diag(Loc, diag::warn_printf_asterisk_precision_missing_arg) + << OrigFormatExpr->getSourceRange(); + else + Diag(Loc, diag::warn_printf_asterisk_width_missing_arg) + << OrigFormatExpr->getSourceRange(); + + // Don't do any more checking. We'll just emit spurious errors. + return; + } + + // Perform type checking on width/precision specifier. + const Expr *E = TheCall->getArg(format_idx+numConversions); + if (const BuiltinType *BT = E->getType()->getAsBuiltinType()) + if (BT->getKind() == BuiltinType::Int) + break; + SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, StrIdx); - + if (Str[StrIdx-1] == '.') - Diag(Loc, diag::warn_printf_asterisk_precision_missing_arg) - << OrigFormatExpr->getSourceRange(); + Diag(Loc, diag::warn_printf_asterisk_precision_wrong_type) + << E->getType() << E->getSourceRange(); else - Diag(Loc, diag::warn_printf_asterisk_width_missing_arg) - << OrigFormatExpr->getSourceRange(); + Diag(Loc, diag::warn_printf_asterisk_width_wrong_type) + << E->getType() << E->getSourceRange(); - // Don't do any more checking. We'll just emit spurious errors. - return; + break; } - - // Perform type checking on width/precision specifier. - const Expr *E = TheCall->getArg(format_idx+numConversions); - if (const BuiltinType *BT = E->getType()->getAsBuiltinType()) - if (BT->getKind() == BuiltinType::Int) - break; - - SourceLocation Loc = getLocationOfStringLiteralByte(FExpr, StrIdx); - - if (Str[StrIdx-1] == '.') - Diag(Loc, diag::warn_printf_asterisk_precision_wrong_type) - << E->getType() << E->getSourceRange(); - else - Diag(Loc, diag::warn_printf_asterisk_width_wrong_type) - << E->getType() << E->getSourceRange(); - - break; } // Characters which can terminate a format conversion |