forked from OSchip/llvm-project
[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.) llvm-svn: 178684
This commit is contained in:
parent
ddef54cad6
commit
ede0983f88
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue