aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-05-03 02:13:53 +0000
committerAnna Zaks <ganna@apple.com>2012-05-03 02:13:53 +0000
commitda3960347a5d563d6746cb363b25466282a09ce3 (patch)
treefbd2adaa6c7c3133329ae639bce6a1d9f8442d34
parentbaeaa9ad120f60b1c5b6f1a84286b507dbe2b55d (diff)
[analyzer] Do not assert on constructing SymSymExpr with diff types.
The resulting type info is stored in the SymSymExpr, so no reason not to support construction of expression with different subexpression types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156051 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp1
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp15
-rw-r--r--test/Analysis/taint-generic.c9
3 files changed, 18 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp
index d286f495cd..d005c2af96 100644
--- a/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -61,7 +61,6 @@ NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs,
NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
const SymExpr *rhs, QualType type) {
assert(lhs && rhs);
- assert(haveSameType(lhs->getType(Context), rhs->getType(Context)) == true);
assert(!Loc::isLocType(type));
return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type));
}
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index 2522cbbd24..4a4fcf3c1f 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -280,6 +280,9 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
BinaryOperator::Opcode op,
NonLoc lhs, NonLoc rhs,
QualType resultTy) {
+ NonLoc InputLHS = lhs;
+ NonLoc InputRHS = rhs;
+
// Handle trivial case where left-side and right-side are the same.
if (lhs == rhs)
switch (op) {
@@ -327,7 +330,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
return makeTruthVal(true, resultTy);
default:
// This case also handles pointer arithmetic.
- return makeSymExprValNN(state, op, lhs, rhs, resultTy);
+ return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
}
}
}
@@ -389,9 +392,9 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
if (lhsValue == 0)
// At this point lhs and rhs have been swapped.
return rhs;
- return makeSymExprValNN(state, op, rhs, lhs, resultTy);
+ return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
default:
- return makeSymExprValNN(state, op, rhs, lhs, resultTy);
+ return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
}
}
}
@@ -406,7 +409,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
dyn_cast<SymIntExpr>(selhs->getSymbol());
if (!symIntExpr)
- return makeSymExprValNN(state, op, lhs, rhs, resultTy);
+ return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
// Is this a logical not? (!x is represented as x == 0.)
if (op == BO_EQ && rhs.isZeroConstant()) {
@@ -454,7 +457,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
// For now, only handle expressions whose RHS is a constant.
const nonloc::ConcreteInt *rhsInt = dyn_cast<nonloc::ConcreteInt>(&rhs);
if (!rhsInt)
- return makeSymExprValNN(state, op, lhs, rhs, resultTy);
+ return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
// If both the LHS and the current expression are additive,
// fold their constants.
@@ -539,7 +542,7 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
resultTy);
}
- return makeSymExprValNN(state, op, lhs, rhs, resultTy);
+ return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy);
}
}
}
diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c
index 1cfdfead64..8ee1896e96 100644
--- a/test/Analysis/taint-generic.c
+++ b/test/Analysis/taint-generic.c
@@ -203,3 +203,12 @@ unsigned radar11369570_hanging(const unsigned char *arr, int l) {
}
return 5/a; // expected-warning {{Division by a tainted value, possibly zero}}
}
+
+// Check that we do not assert of the following code.
+int SymSymExprWithDiffTypes(void* p) {
+ int i;
+ scanf("%d", &i);
+ int j = (i % (int)(long)p);
+ return 5/j; // expected-warning {{Division by a tainted value, possibly zero}}
+}
+