aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2013-04-03 19:28:12 +0000
committerAnna Zaks <ganna@apple.com>2013-04-03 19:28:12 +0000
commitc1bef5671e682de5a573c7c6b66871b36de0ec61 (patch)
tree5fa0fc1ee15aac245797201084c987195bcc7090
parent3d3fb9078f0112fa51d8d9862221f5544c5c80e7 (diff)
[analyzer] Properly handle the ternary operator in trackNullOrUndefValue
1) Look for the node where the condition expression is live when checking if it is constrained to true or false. 2) Fix a bug in ProgramState::isNull, which was masking the problem. When the expression is not a symbol (,which is the case when it is Unknown) return unconstrained value, instead of value constrained to “false”! (Thankfully other callers of isNull have not been effected by the bug.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178684 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp27
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp6
-rw-r--r--test/Analysis/inlining/false-positive-suppression.c5
3 files changed, 26 insertions, 12 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 5f364304e8..7f71b8e81e 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -800,14 +800,22 @@ static const Expr *peelOffOuterExpr(const Stmt *S,
// Peel off the ternary operator.
if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
- ProgramStateRef State = N->getState();
- SVal CondVal = State->getSVal(CO->getCond(), N->getLocationContext());
- if (State->isNull(CondVal).isConstrainedTrue()) {
- return CO->getTrueExpr();
- } else {
- assert(State->isNull(CondVal).isConstrainedFalse());
- return CO->getFalseExpr();
- }
+ const Expr *CondEx = CO->getCond();
+
+ // Find a node where the value of the condition is known.
+ do {
+ ProgramStateRef State = N->getState();
+ SVal CondVal = State->getSVal(CondEx, N->getLocationContext());
+ ConditionTruthVal CondEvaluated = State->isNull(CondVal);
+ if (CondEvaluated.isConstrained()) {
+ if (CondEvaluated.isConstrainedTrue())
+ return CO->getFalseExpr();
+ else
+ return CO->getTrueExpr();
+ }
+ N = N->getFirstPred();
+ } while (N);
+
}
}
return 0;
@@ -820,9 +828,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
if (!S || !N)
return false;
- if (const Expr *Ex = peelOffOuterExpr(S, N)) {
+ if (const Expr *Ex = peelOffOuterExpr(S, N))
S = Ex;
- }
const Expr *Inner = 0;
if (const Expr *Ex = dyn_cast<Expr>(S)) {
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index f3e80f19c9..bff2242925 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -380,9 +380,13 @@ ConditionTruthVal ProgramState::isNull(SVal V) const {
if (V.isZeroConstant())
return true;
+ if (V.isConstant())
+ return false;
+
SymbolRef Sym = V.getAsSymbol();
if (!Sym)
- return false;
+ return ConditionTruthVal();
+
return getStateManager().ConstraintMgr->isNull(this, Sym);
}
diff --git a/test/Analysis/inlining/false-positive-suppression.c b/test/Analysis/inlining/false-positive-suppression.c
index 31ad891762..e12612d8c4 100644
--- a/test/Analysis/inlining/false-positive-suppression.c
+++ b/test/Analysis/inlining/false-positive-suppression.c
@@ -9,6 +9,8 @@ int *getNull() {
return 0;
}
+int* getPtr();
+
int *dynCastToInt(void *ptr) {
if (opaquePropertyCheck(ptr))
return (int *)ptr;
@@ -219,9 +221,10 @@ int derefAssignment(int *p) {
// expected-warning@-2 {{Dereference of null pointer}}
#endif
}
+
void ternaryAssignment(char cond) {
static int x;
- int *p = cond ? &x : getNull();
+ int *p = cond ? getNull() : getPtr();
derefAssignment(p);
}