diff options
-rw-r--r-- | lib/StaticAnalyzer/Core/ProgramState.cpp | 2 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SValBuilder.cpp | 13 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 4 | ||||
-rw-r--r-- | 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<SymbolCast>(sym)->getOperand()); case SymExpr::SymIntKind: return scan(cast<SymIntExpr>(sym)->getLHS()); + case SymExpr::IntSymKind: + return scan(cast<IntSymExpr>(sym)->getRHS()); case SymExpr::SymSymKind: { const SymSymExpr *x = cast<SymSymExpr>(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<nonloc::ConcreteInt>(&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<SymbolCast>(SE)) { - itr.push_back(SC->getOperand()); - return; - } - if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) { - itr.push_back(SIE->getLHS()); - return; - } - else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(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<SymbolCast>(SE)->getOperand()); + return; + case SymExpr::SymIntKind: + itr.push_back(cast<SymIntExpr>(SE)->getLHS()); + return; + case SymExpr::IntSymKind: + itr.push_back(cast<IntSymExpr>(SE)->getRHS()); + return; + case SymExpr::SymSymKind: { + const SymSymExpr *x = cast<SymSymExpr>(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<SymIntExpr>(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<IntSymExpr>(); + new (data) IntSymExpr(lhs, op, rhs, t); + DataSet.InsertNode(data, InsertPos); + } + + return cast<IntSymExpr>(data); +} + const SymSymExpr *SymbolManager::getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, |