aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-07-19 18:10:08 +0000
committerJordan Rose <jordan_rose@apple.com>2012-07-19 18:10:08 +0000
commit48716663e421472cbd590af160a372bc490205e8 (patch)
tree06a1999a84e99c77cb55372edb040a39def39513 /lib/Sema/SemaChecking.cpp
parentee7af50cc7999a2e5101da80bef0fdcff8c90b11 (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.cpp27
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;