diff options
author | Anna Zaks <ganna@apple.com> | 2011-12-05 18:58:25 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2011-12-05 18:58:25 +0000 |
commit | a636fbe73f1ee04d1b3172ffc2914e08a78ec490 (patch) | |
tree | e8d42b749b723166db8117eb3b5289d537bfbb84 /clang/lib | |
parent | 51090d5f7f4246c38d746bbb10642f64c51d2329 (diff) | |
download | bcm5719-llvm-a636fbe73f1ee04d1b3172ffc2914e08a78ec490.tar.gz bcm5719-llvm-a636fbe73f1ee04d1b3172ffc2914e08a78ec490.zip |
[analyzer] Remove all uses of ConstraintManager::canResonAbout() from
ExprEngine.
Teach SimpleConstraintManager::assumeSymRel() to propagate constraints
to symbolic expressions.
+ One extra warning (real bug) is now generated due to enhanced
assumeSymRel().
llvm-svn: 145832
Diffstat (limited to 'clang/lib')
4 files changed, 52 insertions, 53 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 0f49acca936..12b658eb2d2 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -121,8 +121,7 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, SVal LHSVal; - if (Result.isUnknown() || - !getConstraintManager().canReasonAbout(Result)) { + if (Result.isUnknown()) { unsigned Count = currentBuilderContext->getCurrentBlockCount(); @@ -358,8 +357,7 @@ void ExprEngine::VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, // Recover some path-sensitivity if a scalar value evaluated to // UnknownVal. - if ((InitVal.isUnknown() || - !getConstraintManager().canReasonAbout(InitVal)) && + if ((InitVal.isUnknown()) && !VD->getType()->isReferenceType() && !Pred->getState()->isTainted(InitVal)) { InitVal = svalBuilder.getConjuredSymbolVal(NULL, InitEx, @@ -726,7 +724,7 @@ void ExprEngine::VisitIncrementDecrementOperator(const UnaryOperator* U, SVal Result = evalBinOp(state, Op, V2, RHS, U->getType()); // Conjure a new symbol if necessary to recover precision. - if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){ + if (Result.isUnknown()){ DefinedOrUnknownSVal SymVal = svalBuilder.getConjuredSymbolVal(NULL, Ex, currentBuilderContext->getCurrentBlockCount()); diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index a93b5bfd645..79f4348b7c1 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -550,9 +550,8 @@ bool ScanReachableSymbols::scan(const SymExpr *sym) { return true; isVisited = 1; - if (const SymbolData *sData = dyn_cast<SymbolData>(sym)) - if (!visitor.VisitSymbol(sData)) - return false; + if (!visitor.VisitSymbol(sym)) + return false; switch (sym->getKind()) { case SymExpr::RegionValueKind: diff --git a/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp index 4ae1f17eea6..8b7c2c1398a 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp @@ -212,6 +212,40 @@ const ProgramState *SimpleConstraintManager::assumeAux(const ProgramState *state } // end switch } +static llvm::APSInt computeAdjustment(const SymExpr *LHS, + SymbolRef &Sym) { + llvm::APSInt DefaultAdjustment; + DefaultAdjustment = 0; + + // First check if the LHS is a simple symbol reference. + if (isa<SymbolData>(LHS)) + return DefaultAdjustment; + + // Next, see if it's a "($sym+constant1)" expression. + const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS); + + // We cannot simplify "($sym1+$sym2)". + if (!SE) + return DefaultAdjustment; + + // Get the constant out of the expression "($sym+constant1)" or + // "<expr>+constant1". + Sym = SE->getLHS(); + switch (SE->getOpcode()) { + case BO_Add: + return SE->getRHS(); + break; + case BO_Sub: + return -SE->getRHS(); + break; + default: + // We cannot simplify non-additive operators. + return DefaultAdjustment; + } + + return DefaultAdjustment; +} + const ProgramState *SimpleConstraintManager::assumeSymRel(const ProgramState *state, const SymExpr *LHS, BinaryOperator::Opcode op, @@ -219,48 +253,15 @@ const ProgramState *SimpleConstraintManager::assumeSymRel(const ProgramState *st assert(BinaryOperator::isComparisonOp(op) && "Non-comparison ops should be rewritten as comparisons to zero."); - // We only handle simple comparisons of the form "$sym == constant" - // or "($sym+constant1) == constant2". - // The adjustment is "constant1" in the above expression. It's used to - // "slide" the solution range around for modular arithmetic. For example, - // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which - // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to - // the subclasses of SimpleConstraintManager to handle the adjustment. - llvm::APSInt Adjustment; - - // First check if the LHS is a simple symbol reference. - SymbolRef Sym = dyn_cast<SymbolData>(LHS); - if (Sym) { - Adjustment = 0; - } else { - // Next, see if it's a "($sym+constant1)" expression. - const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS); - - // We don't handle "($sym1+$sym2)". - // Give up and assume the constraint is feasible. - if (!SE) - return state; - - // We don't handle "(<expr>+constant1)". - // Give up and assume the constraint is feasible. - Sym = dyn_cast<SymbolData>(SE->getLHS()); - if (!Sym) - return state; - - // Get the constant out of the expression "($sym+constant1)". - switch (SE->getOpcode()) { - case BO_Add: - Adjustment = SE->getRHS(); - break; - case BO_Sub: - Adjustment = -SE->getRHS(); - break; - default: - // We don't handle non-additive operators. - // Give up and assume the constraint is feasible. - return state; - } - } + // We only handle simple comparisons of the form "$sym == constant" + // or "($sym+constant1) == constant2". + // The adjustment is "constant1" in the above expression. It's used to + // "slide" the solution range around for modular arithmetic. For example, + // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which + // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to + // the subclasses of SimpleConstraintManager to handle the adjustment. + SymbolRef Sym = LHS; + llvm::APSInt Adjustment = computeAdjustment(LHS, Sym); // FIXME: This next section is a hack. It silently converts the integers to // be of the same type as the symbol, which is not always correct. Really the diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index f7924319e5b..2e6f33353ec 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -260,9 +260,10 @@ SVal SimpleSValBuilder::MakeSymIntVal(const SymExpr *LHS, // Wrap the LHS up in a NonLoc again and let evalCastFromNonLoc do the // dirty work. if (isIdempotent) { - if (SymbolRef LHSSym = dyn_cast<SymbolData>(LHS)) - return evalCastFromNonLoc(nonloc::SymbolVal(LHSSym), resultTy); - return evalCastFromNonLoc(nonloc::SymExprVal(LHS), resultTy); + if (isa<SymbolData>(LHS)) + return evalCastFromNonLoc(nonloc::SymbolVal(LHS), resultTy); + else + return evalCastFromNonLoc(nonloc::SymExprVal(LHS), resultTy); } // If we reach this point, the expression cannot be simplified. |