From 24d052cdb75d3c1afa5bef32eacaa224e9d0b85d Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Sat, 10 Dec 2011 23:36:51 +0000 Subject: [PATCH] [analyzer] Introduce IntSymExpr, where the integer is on the lhs. Fix a bug in SimpleSValBuilder, where we should swap lhs and rhs when calling generateUnknownVal(), - the function which creates symbolic expressions when data is tainted. The issue is not visible when we only create the expressions for taint since all expressions are commutative from taint perspective. Refactor SymExpr::symbol_iterator::expand() to use a switch instead of a chain of ifs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146336 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/ProgramState.cpp | 2 + lib/StaticAnalyzer/Core/SValBuilder.cpp | 13 ++++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 4 +- lib/StaticAnalyzer/Core/SymbolManager.cpp | 62 +++++++++++++++---- 4 files changed, 66 insertions(+), 15 deletions(-) diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp index 807def26ff..43b0b3e942 100644 --- a/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -565,6 +565,8 @@ bool ScanReachableSymbols::scan(const SymExpr *sym) { return scan(cast(sym)->getOperand()); case SymExpr::SymIntKind: return scan(cast(sym)->getLHS()); + case SymExpr::IntSymKind: + return scan(cast(sym)->getRHS()); case SymExpr::SymSymKind: { const SymSymExpr *x = cast(sym); return scan(x->getLHS()) && scan(x->getRHS()); diff --git a/lib/StaticAnalyzer/Core/SValBuilder.cpp b/lib/StaticAnalyzer/Core/SValBuilder.cpp index f381f1a5ad..81f84f90ae 100644 --- a/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -47,6 +47,14 @@ NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, return nonloc::SymbolVal(SymMgr.getSymIntExpr(lhs, op, rhs, type)); } +NonLoc SValBuilder::makeNonLoc(const llvm::APSInt& lhs, + BinaryOperator::Opcode op, const SymExpr *rhs, + QualType type) { + assert(rhs); + assert(!Loc::isLocType(type)); + return nonloc::SymbolVal(SymMgr.getIntSymExpr(lhs, op, rhs, type)); +} + NonLoc SValBuilder::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType type) { assert(lhs && rhs); @@ -173,6 +181,11 @@ SVal SValBuilder::generateUnknownVal(const ProgramState *State, return makeNonLoc(symLHS, Op, rInt->getValue(), ResultTy); } + if (const nonloc::ConcreteInt *lInt = dyn_cast(&LHS)) { + symRHS = RHS.getAsSymExpr(); + return makeNonLoc(symRHS, Op, lInt->getValue(), ResultTy); + } + symLHS = LHS.getAsSymExpr(); symRHS = RHS.getAsSymExpr(); return makeNonLoc(symLHS, Op, symRHS, ResultTy); diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index a7b67fbe8a..70901aa608 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -388,9 +388,9 @@ SVal SimpleSValBuilder::evalBinOpNN(const ProgramState *state, if (lhsValue == 0) // At this point lhs and rhs have been swapped. return rhs; - return generateUnknownVal(state, op, lhs, rhs, resultTy); + return generateUnknownVal(state, op, rhs, lhs, resultTy); default: - return generateUnknownVal(state, op, lhs, rhs, resultTy); + return generateUnknownVal(state, op, rhs, lhs, resultTy); } } } diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp index e79075f412..6f5d8f90bb 100644 --- a/lib/StaticAnalyzer/Core/SymbolManager.cpp +++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -57,6 +57,15 @@ void SymIntExpr::dumpToStream(raw_ostream &os) const { if (getRHS().isUnsigned()) os << 'U'; } +void IntSymExpr::dumpToStream(raw_ostream &os) const { + os << ' ' << getLHS().getZExtValue(); + if (getLHS().isUnsigned()) os << 'U'; + print(os, getOpcode()); + os << '('; + getRHS()->dumpToStream(os); + os << ") "; +} + void SymSymExpr::dumpToStream(raw_ostream &os) const { os << '('; getLHS()->dumpToStream(os); @@ -125,20 +134,29 @@ void SymExpr::symbol_iterator::expand() { const SymExpr *SE = itr.back(); itr.pop_back(); - if (const SymbolCast *SC = dyn_cast(SE)) { - itr.push_back(SC->getOperand()); - return; - } - if (const SymIntExpr *SIE = dyn_cast(SE)) { - itr.push_back(SIE->getLHS()); - return; - } - else if (const SymSymExpr *SSE = dyn_cast(SE)) { - itr.push_back(SSE->getLHS()); - itr.push_back(SSE->getRHS()); - return; + switch (SE->getKind()) { + case SymExpr::RegionValueKind: + case SymExpr::ConjuredKind: + case SymExpr::DerivedKind: + case SymExpr::ExtentKind: + case SymExpr::MetadataKind: + return; + case SymExpr::CastSymbolKind: + itr.push_back(cast(SE)->getOperand()); + return; + case SymExpr::SymIntKind: + itr.push_back(cast(SE)->getLHS()); + return; + case SymExpr::IntSymKind: + itr.push_back(cast(SE)->getRHS()); + return; + case SymExpr::SymSymKind: { + const SymSymExpr *x = cast(SE); + itr.push_back(x->getLHS()); + itr.push_back(x->getRHS()); + return; + } } - llvm_unreachable("unhandled expansion case"); } @@ -262,6 +280,24 @@ const SymIntExpr *SymbolManager::getSymIntExpr(const SymExpr *lhs, return cast(data); } +const IntSymExpr *SymbolManager::getIntSymExpr(const llvm::APSInt& lhs, + BinaryOperator::Opcode op, + const SymExpr *rhs, + QualType t) { + llvm::FoldingSetNodeID ID; + IntSymExpr::Profile(ID, lhs, op, rhs, t); + void *InsertPos; + SymExpr *data = DataSet.FindNodeOrInsertPos(ID, InsertPos); + + if (!data) { + data = (IntSymExpr*) BPAlloc.Allocate(); + new (data) IntSymExpr(lhs, op, rhs, t); + DataSet.InsertNode(data, InsertPos); + } + + return cast(data); +} + const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, -- 2.40.0