diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-19 18:10:08 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-19 18:10:08 +0000 |
commit | 48716663e421472cbd590af160a372bc490205e8 (patch) | |
tree | 06a1999a84e99c77cb55372edb040a39def39513 /lib/Sema/SemaChecking.cpp | |
parent | ee7af50cc7999a2e5101da80bef0fdcff8c90b11 (diff) |
Don't crash checking a format string if one of the arguments is invalid.
Previously, we would ask for the SourceLocation of an argument even if
it were NULL (i.e. if Sema resulted in an ExprError trying to build it).
<rdar://problem/11890818>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160515 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index c0597cddd5..1f57b26c9e 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2085,6 +2085,8 @@ void CheckFormatHandler::HandleNullChar(const char *nullCharacter) { } } +// Note that this may return NULL if there was an error parsing or building +// one of the argument expressions. const Expr *CheckFormatHandler::getDataArg(unsigned i) const { return Args[FirstDataArg + i]; } @@ -2098,11 +2100,13 @@ void CheckFormatHandler::DoneProcessing() { signed notCoveredArg = CoveredArgs.find_first(); if (notCoveredArg >= 0) { assert((unsigned)notCoveredArg < NumDataArgs); - SourceLocation Loc = getDataArg((unsigned) notCoveredArg)->getLocStart(); - if (!S.getSourceManager().isInSystemMacro(Loc)) { - EmitFormatDiagnostic(S.PDiag(diag::warn_printf_data_arg_not_used), - Loc, - /*IsStringLocation*/false, getFormatStringRange()); + if (const Expr *E = getDataArg((unsigned) notCoveredArg)) { + SourceLocation Loc = E->getLocStart(); + if (!S.getSourceManager().isInSystemMacro(Loc)) { + EmitFormatDiagnostic(S.PDiag(diag::warn_printf_data_arg_not_used), + Loc, /*IsStringLocation*/false, + getFormatStringRange()); + } } } } @@ -2310,6 +2314,9 @@ bool CheckPrintfHandler::HandleAmount( // doesn't emit a warning for that case. CoveredArgs.set(argIndex); const Expr *Arg = getDataArg(argIndex); + if (!Arg) + return false; + QualType T = Arg->getType(); const analyze_printf::ArgTypeResult &ATR = Amt.getArgType(S.Context); @@ -2571,8 +2578,11 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex)) return false; - return checkFormatExpr(FS, startSpecifier, specifierLen, - getDataArg(argIndex)); + const Expr *Arg = getDataArg(argIndex); + if (!Arg) + return true; + + return checkFormatExpr(FS, startSpecifier, specifierLen, Arg); } bool @@ -2788,6 +2798,9 @@ bool CheckScanfHandler::HandleScanfSpecifier( // Check that the argument type matches the format specifier. const Expr *Ex = getDataArg(argIndex); + if (!Ex) + return true; + const analyze_scanf::ScanfArgTypeResult &ATR = FS.getArgType(S.Context); if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) { ScanfSpecifier fixedFS = FS; |