diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-02-25 17:51:31 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-02-25 17:51:31 +0000 |
commit | 07d83aa220567bef263ef76cfc9b0159320bb640 (patch) | |
tree | 5466fe5c22d3a45f469287dbd938ef4afd521f3a | |
parent | 3426b9bdc236df389f3aa00b56bf9154659511f2 (diff) |
Added transfer function support for checking for divide-by-zero errors.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47547 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Analysis/GRExprEngine.cpp | 56 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/GRExprEngine.h | 18 |
2 files changed, 70 insertions, 4 deletions
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp index 2931d2aa6d..74fadcc9e3 100644 --- a/Analysis/GRExprEngine.cpp +++ b/Analysis/GRExprEngine.cpp @@ -850,6 +850,33 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, BinaryOperator::Opcode Op = B->getOpcode(); + if (Op == BinaryOperator::Div) { // Check for divide-by-zero. + + // First, "assume" that the denominator is 0. + + bool isFeasible = false; + StateTy ZeroSt = Assume(St, RightV, false, isFeasible); + + if (isFeasible) { + NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2); + + if (DivZeroNode) { + DivZeroNode->markAsSink(); + DivZeroes.insert(DivZeroNode); + } + } + + // Second, "assume" that the denominator cannot be 0. + + isFeasible = false; + St = Assume(St, RightV, true, isFeasible); + + if (!isFeasible) + continue; + + // Fall-through. The logic below processes the divide. + } + if (Op <= BinaryOperator::Or) { // Process non-assignements except commas or short-circuited @@ -964,8 +991,35 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, RightV = EvalCast(RightV, CTy); // Evaluate operands and promote to result type. + + if (Op == BinaryOperator::Div) { // Check for divide-by-zero. + + // First, "assume" that the denominator is 0. + + bool isFeasible = false; + StateTy ZeroSt = Assume(St, RightV, false, isFeasible); + + if (isFeasible) { + NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2); + + if (DivZeroNode) { + DivZeroNode->markAsSink(); + DivZeroes.insert(DivZeroNode); + } + } + + // Second, "assume" that the denominator cannot be 0. + + isFeasible = false; + St = Assume(St, RightV, true, isFeasible); + + if (!isFeasible) + continue; + + // Fall-through. The logic below processes the divide. + } + RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType()); - St = SetRVal(SetRVal(St, B, Result), LeftLV, Result); } } diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index 7fa5297daa..bc8bec78e1 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -114,18 +114,30 @@ protected: /// taking a branch based on an uninitialized value. typedef llvm::SmallPtrSet<NodeTy*,5> UninitBranchesTy; UninitBranchesTy UninitBranches; + + typedef llvm::SmallPtrSet<NodeTy*,5> UninitStoresTy; + typedef llvm::SmallPtrSet<NodeTy*,5> BadDerefTy; + typedef llvm::SmallPtrSet<NodeTy*,5> DivZerosTy; /// UninitStores - Sinks in the ExplodedGraph that result from /// making a store to an uninitialized lvalue. - typedef llvm::SmallPtrSet<NodeTy*,5> UninitStoresTy; UninitStoresTy UninitStores; /// ImplicitNullDeref - Nodes in the ExplodedGraph that result from - /// taking a dereference on a symbolic pointer that may be NULL. - typedef llvm::SmallPtrSet<NodeTy*,5> BadDerefTy; + /// taking a dereference on a symbolic pointer that MAY be NULL. BadDerefTy ImplicitNullDeref; + + /// ExplicitNullDeref - Nodes in the ExplodedGraph that result from + /// taking a dereference on a symbolic pointer that MUST be NULL. BadDerefTy ExplicitNullDeref; + + /// UnitDeref - Nodes in the ExplodedGraph that result from + /// taking a dereference on an uninitialized value. BadDerefTy UninitDeref; + + /// DivZeroes - Nodes in the ExplodedGraph that result from evaluating + /// a divide-by-zero. + DivZerosTy DivZeroes; bool StateCleaned; |