Index: include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -63,9 +63,12 @@ public: ConstraintManager() : NotifyAssumeClients(true) {} + virtual bool uglyEval(const SymSymExpr *SSE, ProgramStateRef state) { + return false; + } + virtual ~ConstraintManager(); - virtual ProgramStateRef assume(ProgramStateRef state, - DefinedSVal Cond, + virtual ProgramStateRef assume(ProgramStateRef state, DefinedSVal Cond, bool Assumption) = 0; typedef std::pair ProgramStatePair; Index: lib/StaticAnalyzer/Core/RangeConstraintManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -287,6 +287,8 @@ RangeConstraintManager(SubEngine *SE, SValBuilder &SVB) : RangedConstraintManager(SE, SVB) {} + virtual bool uglyEval(const SymSymExpr *SSE, ProgramStateRef state); + //===------------------------------------------------------------------===// // Implementation for interface from ConstraintManager. //===------------------------------------------------------------------===// @@ -723,6 +725,25 @@ // Pretty-printing. //===------------------------------------------------------------------------===/ +bool RangeConstraintManager::uglyEval(const SymSymExpr *SSE, + ProgramStateRef State) { + ConstraintRangeTy Ranges = State->get(); + for (ConstraintRangeTy::iterator I = Ranges.begin(), E = Ranges.end(); I != E; + ++I) { + SymbolRef SR = I.getKey(); + if (const SymSymExpr *SSE2 = dyn_cast(SR)) { + if (SSE->getOpcode() != SSE2->getOpcode()) + continue; + if (SSE->getLHS() != SSE2->getLHS()) + continue; + if (SSE->getRHS() != SSE2->getRHS()) + continue; + return true; + } + } + return false; +} + void RangeConstraintManager::print(ProgramStateRef St, raw_ostream &Out, const char *nl, const char *sep) { Index: lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp +++ lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp @@ -53,6 +53,19 @@ ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State, NonLoc Cond, bool Assumption) { + if (1) { + Optional SymVal = Cond.getAs(); + if (SymVal && SymVal->isExpression()) { + const SymExpr *SE = SymVal->getSymbol(); + if (const SymSymExpr *SSE = dyn_cast(SE)) { + if (SSE->getOpcode() == BO_GE) { + SymSymExpr SSE2(SSE->getRHS(), BO_EQ, SSE->getLHS(), SSE->getType()); + if (State->getConstraintManager().uglyEval(&SSE2, State)) + return Assumption ? State : nullptr; + } + } + } + } // We cannot reason about SymSymExprs, and can only reason about some // SymIntExprs. Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -547,6 +547,13 @@ if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs)) return MakeSymIntVal(Sym, op, *RHSValue, resultTy); + if (!state->isTainted(rhs) && !state->isTainted(lhs)) { + const SymExpr *lhse = lhs.getAsSymExpr(); + const SymExpr *rhse = rhs.getAsSymExpr(); + return nonloc::SymbolVal( + SymMgr.getSymSymExpr(lhse, op, rhse, resultTy)); + } + // Give up -- this is not a symbolic expression we can handle. return makeSymExprValNN(state, op, InputLHS, InputRHS, resultTy); }