summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2011-11-17 23:07:28 +0000
committerAnna Zaks <ganna@apple.com>2011-11-17 23:07:28 +0000
commit040ddfedc0206f8866ad8f42060bea6cc82d64b7 (patch)
tree66a0f1433d6bef8e1037ce177b9e20dd109202e1 /clang/lib/StaticAnalyzer
parentb42cfa0015577ae6dddac8acb276ea254b60453b (diff)
downloadbcm5719-llvm-040ddfedc0206f8866ad8f42060bea6cc82d64b7.tar.gz
bcm5719-llvm-040ddfedc0206f8866ad8f42060bea6cc82d64b7.zip
[analyzer] Do not conjure a symbol when we need to propagate taint.
When the solver and SValBuilder cannot reason about symbolic expressions (ex: (x+1)*y ), the analyzer conjures a new symbol with no ties to the past. This helps it to recover some path-sensitivity. However, this breaks the taint propagation. With this commit, we are going to construct the expression even if we cannot reason about it later on if an operand is tainted. Also added some comments and asserts. llvm-svn: 144932
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp3
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp25
-rw-r--r--clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp14
3 files changed, 34 insertions, 8 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index b82dfea58de..d74c48d962c 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -361,7 +361,8 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred,
// UnknownVal.
if ((InitVal.isUnknown() ||
!getConstraintManager().canReasonAbout(InitVal)) &&
- !VD->getType()->isReferenceType()) {
+ !VD->getType()->isReferenceType() &&
+ !Pred->getState()->isTainted(InitVal)) {
InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx,
currentBuilderContext->getCurrentBlockCount());
}
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index f118f4a0f09..db2097c16f2 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -43,12 +43,14 @@ NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
// The Environment ensures we always get a persistent APSInt in
// BasicValueFactory, so we don't need to get the APSInt from
// BasicValueFactory again.
+ assert(lhs);
assert(!Loc::isLocType(type));
return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, rhs, type));
}
NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
const SymExpr *rhs, QualType type) {
+ assert(lhs && rhs);
assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
assert(!Loc::isLocType(type));
return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, type));
@@ -162,6 +164,29 @@ DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
//===----------------------------------------------------------------------===//
+SVal SValBuilder::generateUnknownVal(const ProgramState *State,
+ BinaryOperator::Opcode Op,
+ NonLoc LHS, NonLoc RHS,
+ QualType ResultTy) {
+ // If operands are tainted, create a symbol to ensure that we propagate taint.
+ if (State->isTainted(RHS) || State->isTainted(LHS)) {
+ const SymExpr *symLHS;
+ const SymExpr *symRHS;
+
+ if (const nonloc::ConcreteInt *rInt = dyn_cast<nonloc::ConcreteInt>(&RHS)) {
+ symLHS = LHS.getAsSymExpr();
+ return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy);
+ }
+ // TODO: Handle the case when lhs is ConcreteInt.
+
+ symLHS = LHS.getAsSymExpr();
+ symRHS = RHS.getAsSymExpr();
+ return makeNonLoc(symLHS, Op, symRHS, ResultTy);
+ }
+ return UnknownVal();
+}
+
+
SVal SValBuilder::evalBinOp(const ProgramState *state, BinaryOperator::Opcode op,
SVal lhs, SVal rhs, QualType type) {
diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index bd63ecf775d..f7924319e5b 100644
--- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -298,7 +298,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
while (1) {
switch (lhs.getSubKind()) {
default:
- return UnknownVal();
+ return generateUnknownVal(state, op, lhs, rhs, resultTy);
case nonloc::LocAsIntegerKind: {
Loc lhsL = cast<nonloc::LocAsInteger>(lhs).getLoc();
switch (rhs.getSubKind()) {
@@ -321,7 +321,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
return makeTruthVal(true, resultTy);
default:
// This case also handles pointer arithmetic.
- return UnknownVal();
+ return generateUnknownVal(state, op, lhs, rhs, resultTy);
}
}
}
@@ -333,7 +333,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
dyn_cast<SymIntExpr>(selhs->getSymbolicExpression());
if (!symIntExpr)
- return UnknownVal();
+ return generateUnknownVal(state, op, lhs, rhs, resultTy);
// Is this a logical not? (!x is represented as x == 0.)
if (op == BO_EQ && rhs.isZeroConstant()) {
@@ -381,7 +381,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
// For now, only handle expressions whose RHS is a constant.
const nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs);
if (!rhsInt)
- return UnknownVal();
+ return generateUnknownVal(state, op, lhs, rhs, resultTy);
// If both the LHS and the current expression are additive,
// fold their constants.
@@ -467,9 +467,9 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
if (lhsValue == 0)
// At this point lhs and rhs have been swapped.
return rhs;
- return UnknownVal();
+ return generateUnknownVal(state, op, lhs, rhs, resultTy);
default:
- return UnknownVal();
+ return generateUnknownVal(state, op, lhs, rhs, resultTy);
}
}
}
@@ -529,7 +529,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
resultTy);
}
- return UnknownVal();
+ return generateUnknownVal(state, op, lhs, rhs, resultTy);
}
}
}
OpenPOWER on IntegriCloud