Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -20,6 +20,20 @@ using namespace ento; using llvm::APSInt; +/// 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. +static void conjureOffsetSymbolOnLocation( + SVal &Symbol, SVal Other, Expr* Expression, SValBuilder &svalBuilder, + unsigned Count, const LocationContext *LCtx) { + QualType Ty = Expression->getType(); + if (Other.getAs() && + Ty->isIntegralOrEnumerationType() && + Symbol.isUnknown()) { + Symbol = svalBuilder.conjureSymbolVal(Expression, LCtx, Ty, Count); + } +} + void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, ExplodedNodeSet &Dst) { @@ -63,24 +77,13 @@ StmtNodeBuilder Bldr(*it, Tmp2, *currBldrCtx); 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 = currBldrCtx->blockCount(); - if (LeftV.getAs() && - RHS->getType()->isIntegralOrEnumerationType() && - RightV.isUnknown()) { - RightV = svalBuilder.conjureSymbolVal(RHS, LCtx, RHS->getType(), - Count); - } - if (RightV.getAs() && - LHS->getType()->isIntegralOrEnumerationType() && - LeftV.isUnknown()) { - LeftV = svalBuilder.conjureSymbolVal(LHS, LCtx, LHS->getType(), - Count); - } + conjureOffsetSymbolOnLocation( + RightV, LeftV, RHS, svalBuilder, Count, LCtx); + conjureOffsetSymbolOnLocation( + LeftV, RightV, LHS, svalBuilder, Count, LCtx); } // Although we don't yet model pointers-to-members, we do need to make