danielmarjamaki updated this revision to Diff 113969.
danielmarjamaki added a comment.

minor code cleanup


Repository:
  rL LLVM

https://reviews.llvm.org/D36471

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  lib/StaticAnalyzer/Core/RangeConstraintManager.cpp

Index: lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
===================================================================
--- lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -304,6 +304,8 @@
   void print(ProgramStateRef State, raw_ostream &Out, const char *nl,
              const char *sep) override;
 
+  ProgramStateRef evalRangeOp(ProgramStateRef state, SVal V) override;
+
   //===------------------------------------------------------------------===//
   // Implementation for interface from RangedConstraintManager.
   //===------------------------------------------------------------------===//
@@ -741,3 +743,56 @@
   }
   Out << nl;
 }
+
+ProgramStateRef RangeConstraintManager::evalRangeOp(ProgramStateRef St,
+                                                    SVal V) {
+  const SymExpr *SE = V.getAsSymExpr();
+  if (!SE)
+    return nullptr;
+
+  const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE);
+  if (!SIE)
+    return nullptr;
+
+  const clang::BinaryOperatorKind Opc = SIE->getOpcode();
+
+  if (Opc != BO_Add && Opc != BO_Sub && Opc != BO_Div)
+    return nullptr;
+
+  const SymExpr *LHS = SIE->getLHS();
+  const llvm::APSInt &RHS = SIE->getRHS();
+
+  ConstraintRangeTy Ranges = St->get<ConstraintRange>();
+  for (ConstraintRangeTy::iterator I = Ranges.begin(), E = Ranges.end(); I != E;
+       ++I) {
+    if (LHS != I.getKey())
+      continue;
+    const auto D = I.getData();
+    for (auto I = D.begin(); I != D.end(); ++I) {
+      if (I->From().isUnsigned() != RHS.isUnsigned())
+        // TODO: Handle sign conversions.
+        return nullptr;
+      if (I->From().getBitWidth() != RHS.getBitWidth())
+        // TODO: Promote values.
+        return nullptr;
+      if (I->From().isNegative())
+        // TODO: Handle negative range values
+        return nullptr;
+
+      BasicValueFactory &BVF = getBasicVals();
+      const llvm::APSInt *Lower = BVF.evalAPSInt(Opc, I->From(), RHS);
+      if (!Lower)
+        return nullptr;
+      const llvm::APSInt *Upper = BVF.evalAPSInt(Opc, I->To(), RHS);
+      if (!Upper)
+        return nullptr;
+
+      SymbolRef Sym = V.getAsSymbol();
+      RangeSet RS =
+          getRange(St, Sym).Intersect(getBasicVals(), F, *Lower, *Upper);
+      // TODO: This only evaluates the first range. Evaluate all ranges.
+      return RS.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, RS);
+    }
+  }
+  return nullptr;
+}
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -98,7 +98,9 @@
       }
 
       state = state->BindExpr(B, LCtx, Result);
-      Bldr.generateNode(B, *it, state);
+      ProgramStateRef state2 =
+          getConstraintManager().evalRangeOp(state, Result);
+      Bldr.generateNode(B, *it, state2 ? state2 : state);
       continue;
     }
 
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
===================================================================
--- include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -142,13 +142,15 @@
   /// Scan all symbols referenced by the constraints. If the symbol is not
   /// alive, remove it.
   virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
-                                                 SymbolReaper& SymReaper) = 0;
+                                             SymbolReaper &SymReaper) = 0;
 
-  virtual void print(ProgramStateRef state,
-                     raw_ostream &Out,
-                     const char* nl,
+  virtual void print(ProgramStateRef state, raw_ostream &Out, const char *nl,
                      const char *sep) = 0;
 
+  virtual ProgramStateRef evalRangeOp(ProgramStateRef state, SVal V) {
+    return nullptr;
+  }
+
   virtual void EndPath(ProgramStateRef state) {}
 
   /// Convenience method to query the state to see if a symbol is null or
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to