diff options
Diffstat (limited to 'clang/Analysis/GRExprEngine.cpp')
| -rw-r--r-- | clang/Analysis/GRExprEngine.cpp | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/clang/Analysis/GRExprEngine.cpp b/clang/Analysis/GRExprEngine.cpp index 6106ef39cb2..74f3a9a48d7 100644 --- a/clang/Analysis/GRExprEngine.cpp +++ b/clang/Analysis/GRExprEngine.cpp @@ -1008,14 +1008,11 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, bool isFeasible = false; ValueState* ZeroSt = Assume(St, RightV, false, isFeasible); - if (isFeasible) { - NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2); - - if (DivZeroNode) { + if (isFeasible) + if (NodeTy* DivZeroNode = Builder->generateNode(B, ZeroSt, N2)) { DivZeroNode->markAsSink(); BadDivides.insert(DivZeroNode); } - } // Second, "assume" that the denominator cannot be 0. @@ -1029,6 +1026,7 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, // Fall-through. The logic below processes the divide. } + if (Op <= BinaryOperator::Or) { // Process non-assignements except commas or short-circuited @@ -1041,6 +1039,18 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, continue; } + if (Result.isUndef() && !LeftV.isUndef() && !RightV.isUndef()) { + + // The operands were not undefined, but the result is undefined. + + if (NodeTy* UndefNode = Builder->generateNode(B, St, N2)) { + UndefNode->markAsSink(); + UndefResults.insert(UndefNode); + } + + continue; + } + Nodify(Dst, B, N2, SetRVal(St, B, Result)); continue; } @@ -1195,6 +1205,19 @@ void GRExprEngine::VisitBinaryOperator(BinaryOperator* B, } RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType()); + + if (Result.isUndef()) { + + // The operands were not undefined, but the result is undefined. + + if (NodeTy* UndefNode = Builder->generateNode(B, St, N2)) { + UndefNode->markAsSink(); + UndefResults.insert(UndefNode); + } + + continue; + } + St = SetRVal(SetRVal(St, B, Result), LeftLV, Result); } } @@ -1591,9 +1614,13 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> : GraphPrintCheckerState->isUndefDeref(N) || GraphPrintCheckerState->isUndefStore(N) || GraphPrintCheckerState->isUndefControlFlow(N) || - GraphPrintCheckerState->isBadDivide(N)) + GraphPrintCheckerState->isBadDivide(N) || + GraphPrintCheckerState->isUndefResult(N)) return "color=\"red\",style=\"filled\""; + if (GraphPrintCheckerState->isNoReturnCall(N)) + return "color=\"blue\",style=\"filled\""; + return ""; } @@ -1635,6 +1662,11 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> : else if (GraphPrintCheckerState->isBadDivide(N)) { Out << "\\|Divide-by zero or undefined value."; } + else if (GraphPrintCheckerState->isUndefResult(N)) { + Out << "\\|Result of operation is undefined."; + } + else if (GraphPrintCheckerState->isNoReturnCall(N)) + Out << "\\|Call to function marked \"noreturn\"."; break; } |

