diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngineC.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ExprEngineC.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 93e598a273..d5555daecd 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -58,6 +58,26 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, if (!B->isAssignmentOp()) { StmtNodeBuilder Bldr(*it, Tmp2, *currentBuilderContext); + + if (B->isAdditiveOp()) { + // If one of the operands is a location, conjure a symbol for the other + // one (offset) if it's unknown so that memory arithmetic always + // results in an ElementRegion. + // TODO: This can be removed after we enable history tracking with + // SymSymExpr. + unsigned Count = currentBuilderContext->getCurrentBlockCount(); + if (isa<Loc>(LeftV) && + RHS->getType()->isIntegerType() && RightV.isUnknown()) { + RightV = svalBuilder.getConjuredSymbolVal(RHS, LCtx, + RHS->getType(), Count); + } + if (isa<Loc>(RightV) && + LHS->getType()->isIntegerType() && LeftV.isUnknown()) { + LeftV = svalBuilder.getConjuredSymbolVal(LHS, LCtx, + LHS->getType(), Count); + } + } + // Process non-assignments except commas or short-circuited // logical expressions (LAnd and LOr). SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType()); |