forked from OSchip/llvm-project
[analyzer] Fix inconsistency on when SValBuilder assumes that 2
types are equivalent. + A taint test which tests bitwise operations and which was triggering an assertion due to presence of the integer to integer cast. llvm-svn: 146240
This commit is contained in:
parent
98e642db2c
commit
6af472aa3b
|
@ -68,6 +68,17 @@ public:
|
|||
|
||||
virtual ~SValBuilder() {}
|
||||
|
||||
bool haveSameType(const SymExpr *Sym1, const SymExpr *Sym2) {
|
||||
return haveSameType(Sym1->getType(Context), Sym2->getType(Context));
|
||||
}
|
||||
|
||||
bool haveSameType(QualType Ty1, QualType Ty2) {
|
||||
// FIXME: Remove the second disjunct when we support symbolic
|
||||
// truncation/extension.
|
||||
return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) ||
|
||||
(Ty2->isIntegerType() && Ty2->isIntegerType()));
|
||||
}
|
||||
|
||||
SVal evalCast(SVal val, QualType castTy, QualType originalType);
|
||||
|
||||
virtual SVal evalMinus(NonLoc val) = 0;
|
||||
|
|
|
@ -37,7 +37,6 @@ DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) {
|
|||
return UnknownVal();
|
||||
}
|
||||
|
||||
|
||||
NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
|
||||
const llvm::APSInt& rhs, QualType type) {
|
||||
// The Environment ensures we always get a persistent APSInt in
|
||||
|
@ -51,7 +50,7 @@ NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
|
|||
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(haveSameType(lhs->getType(Context), rhs->getType(Context)) == true);
|
||||
assert(!Loc::isLocType(type));
|
||||
return nonloc::SymbolVal(SymMgr.getSymSymExpr(lhs, op, rhs, type));
|
||||
}
|
||||
|
|
|
@ -80,16 +80,14 @@ SVal SimpleSValBuilder::evalCastFromNonLoc(NonLoc val, QualType castTy) {
|
|||
|
||||
if (const SymExpr *se = val.getAsSymbolicExpression()) {
|
||||
QualType T = Context.getCanonicalType(se->getType(Context));
|
||||
if (T == Context.getCanonicalType(castTy))
|
||||
return val;
|
||||
|
||||
// If types are the same or both are integers, ignore the cast.
|
||||
// FIXME: Remove this hack when we support symbolic truncation/extension.
|
||||
// HACK: If both castTy and T are integers, ignore the cast. This is
|
||||
// not a permanent solution. Eventually we want to precisely handle
|
||||
// extension/truncation of symbolic integers. This prevents us from losing
|
||||
// precision when we assign 'x = y' and 'y' is symbolic and x and y are
|
||||
// different integer types.
|
||||
if (T->isIntegerType() && castTy->isIntegerType())
|
||||
if (haveSameType(T, castTy))
|
||||
return val;
|
||||
|
||||
if (!isLocType)
|
||||
|
@ -483,7 +481,7 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state,
|
|||
// Otherwise, make a SymbolVal out of the expression.
|
||||
return MakeSymIntVal(symIntExpr, op, rhsInt->getValue(), resultTy);
|
||||
|
||||
// LHS is a simple symbol.
|
||||
// LHS is a simple symbol (not a symbolic expression).
|
||||
} else {
|
||||
nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
|
||||
SymbolRef Sym = slhs->getSymbol();
|
||||
|
|
|
@ -55,3 +55,18 @@ void taintTracking(int x) {
|
|||
int ty = xy.y; // FIXME: This should be tainted as well.
|
||||
char ntz = xy.z;// no warning
|
||||
}
|
||||
|
||||
void BitwiseOp(int in, char inn) {
|
||||
// Taint on bitwise operations, integer to integer cast.
|
||||
int m;
|
||||
int x = 0;
|
||||
scanf("%d", &x);
|
||||
int y = (in << (x << in)) * 5;// expected-warning 4 {{tainted}}
|
||||
// The next line tests integer to integer cast.
|
||||
int z = y & inn; // expected-warning 2 {{tainted}}
|
||||
if (y == 5) // expected-warning 2 {{tainted}}
|
||||
m = z | z;// expected-warning 4 {{tainted}}
|
||||
else
|
||||
m = inn;
|
||||
int mm = m; // expected-warning {{tainted}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue