From f1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 Mon Sep 17 00:00:00 2001
From: "Zancanaro; Carlo" <czan8762@plang3.cs.usyd.edu.au>
Date: Mon, 15 Oct 2012 17:08:15 +1100
Subject: Fix up the Equation System generation. Now there's a bug in the
 solver.

The solver seems to work fine when run as a tool by itself, but not in the clang stuff. Very annoying.
---
 .../Analysis/Analyses/IntervalSolver/Complete.hpp    |  5 +----
 .../Analysis/Analyses/IntervalSolver/Expression.hpp  | 20 ++++++++++++--------
 .../Analysis/Analyses/IntervalSolver/MaxStrategy.hpp |  7 +++++--
 .../Analyses/IntervalSolver/VariableAssignment.hpp   | 12 ++++++++----
 4 files changed, 26 insertions(+), 18 deletions(-)

(limited to 'clang/include')

diff --git a/clang/include/clang/Analysis/Analyses/IntervalSolver/Complete.hpp b/clang/include/clang/Analysis/Analyses/IntervalSolver/Complete.hpp
index 5219c9e..9acb9d0 100644
--- a/clang/include/clang/Analysis/Analyses/IntervalSolver/Complete.hpp
+++ b/clang/include/clang/Analysis/Analyses/IntervalSolver/Complete.hpp
@@ -15,10 +15,7 @@ struct Complete {
     : _value(value), _infinity(false) { }
   Complete(const T& value, const bool& infinity)
     : _value(value), _infinity(infinity) {
-    if (value == 0 && infinity == true) {
-      std::cout << "throw exception" << *(char*)NULL;
-      //throw "Zero infinity? Die die die!";
-    }
+    assert(value != 0 || infinity == false);
   }
   Complete(const Complete& other)
     : _value(other._value), _infinity(other._infinity) { }
diff --git a/clang/include/clang/Analysis/Analyses/IntervalSolver/Expression.hpp b/clang/include/clang/Analysis/Analyses/IntervalSolver/Expression.hpp
index c4ee4c0..ac9b052 100644
--- a/clang/include/clang/Analysis/Analyses/IntervalSolver/Expression.hpp
+++ b/clang/include/clang/Analysis/Analyses/IntervalSolver/Expression.hpp
@@ -28,7 +28,7 @@ struct Expression {
   }
 
   virtual Domain eval(const VariableAssignment<Domain>&) const = 0;
-  virtual Domain eval(const VariableAssignment<Domain>& rho,
+  virtual Domain evalWithStrat(const VariableAssignment<Domain>& rho,
                       const MaxStrategy<Domain>&) const {
     return eval(rho);
   }
@@ -98,16 +98,20 @@ struct OperatorExpression : public Expression<Domain> {
     return _operator.eval(argumentValues);
   }
 
-  virtual Domain eval(const VariableAssignment<Domain>& rho, const MaxStrategy<Domain>& strat) const {
+  virtual Domain evalWithStrat(const VariableAssignment<Domain>& rho, const MaxStrategy<Domain>& strat) const {
     std::vector<Domain> argumentValues;
     for (typename std::vector<Expression<Domain>*>::const_iterator it = _arguments.begin();
          it != _arguments.end();
          ++it) {
-      argumentValues.push_back((*it)->eval(rho, strat));
+      argumentValues.push_back((*it)->evalWithStrat(rho, strat));
     }
     return _operator.eval(argumentValues);
   }
 
+  std::vector<Expression<Domain>*>& arguments() {
+    return _arguments;
+  }
+
   const std::vector<Expression<Domain>*>& arguments() const {
     return _arguments;
   }
@@ -139,7 +143,7 @@ struct OperatorExpression : public Expression<Domain> {
   private:
   const Operator<Domain>& _operator;
   protected:
-  const std::vector<Expression<Domain>*> _arguments;
+  std::vector<Expression<Domain>*> _arguments;
 };
 
 template<typename Domain>
@@ -151,18 +155,18 @@ struct MaxExpression : public OperatorExpression<Domain> {
     return this;
   }
 
-  virtual Domain eval(const VariableAssignment<Domain>& rho, const MaxStrategy<Domain>& strat) const {
-    return this->_arguments[strat.get(*this)]->eval(rho, strat);
+  virtual Domain evalWithStrat(const VariableAssignment<Domain>& rho, const MaxStrategy<Domain>& strat) const {
+    return this->_arguments[strat.get(*this)]->evalWithStrat(rho, strat);
   }
 
   unsigned int bestStrategy(const VariableAssignment<Domain>& rho, const MaxStrategy<Domain>& strat) const {
-    Domain bestValue = this->eval(rho, strat);
+    Domain bestValue = this->evalWithStrat(rho, strat);
     unsigned int bestIndex = strat.get(*this);
 
     for (unsigned int i = 0, length = this->_arguments.size();
          i < length;
          ++i) {
-      const Domain value = this->_arguments[i]->eval(rho, strat);
+      const Domain value = this->_arguments[i]->evalWithStrat(rho, strat);
       if (bestValue < value) {
         bestValue = value;
         bestIndex = i;
diff --git a/clang/include/clang/Analysis/Analyses/IntervalSolver/MaxStrategy.hpp b/clang/include/clang/Analysis/Analyses/IntervalSolver/MaxStrategy.hpp
index f5cb0d8..57dcdeb 100644
--- a/clang/include/clang/Analysis/Analyses/IntervalSolver/MaxStrategy.hpp
+++ b/clang/include/clang/Analysis/Analyses/IntervalSolver/MaxStrategy.hpp
@@ -54,9 +54,12 @@ struct DynamicMaxStrategy : public MaxStrategy<Domain> {
     solver_log::strategy << indent() << "Invalidating " << v << " - " << *_system[v] << std::endl;
     _stable.filter(_var_influence[v]);
 
+    IdSet<MaxExpression<Domain> > infl = _var_influence[v];
+    _var_influence[v].clear();
+
     for (typename IdSet<MaxExpression<Domain> >::iterator
-           it = _var_influence[v].begin(),
-           end = _var_influence[v].end();
+           it = infl.begin(),
+           end = infl.end();
          it != end;
          ++it) {
       solve(_system.maxExpression(*it));
diff --git a/clang/include/clang/Analysis/Analyses/IntervalSolver/VariableAssignment.hpp b/clang/include/clang/Analysis/Analyses/IntervalSolver/VariableAssignment.hpp
index 0bbebfc..ba5f650 100644
--- a/clang/include/clang/Analysis/Analyses/IntervalSolver/VariableAssignment.hpp
+++ b/clang/include/clang/Analysis/Analyses/IntervalSolver/VariableAssignment.hpp
@@ -35,8 +35,12 @@ struct DynamicVariableAssignment : public VariableAssignment<Domain> {
 
   void invalidate(const Variable<Domain>& x) const {
     solver_log::fixpoint << indent() << "Invalidating " << x << std::endl;
-    _stable.remove(x);
-    _values[x] = infinity<Domain>();
+    if (_stable.contains(x)) {
+      _stable.remove(x);
+      _values[x] = infinity<Domain>();
+      
+      solve(x);
+    }
   }
 
 private:
@@ -49,8 +53,8 @@ private:
       stack_depth++;
       if (!_system[x])
         return;
-      Domain val = _system[x]->eval(DependencyAssignment(*this, x),
-                                    _strategy);
+      Domain val = _system[x]->evalWithStrat(DependencyAssignment(*this, x),
+					     _strategy);
       stack_depth--;
 
       if (val != _values[x]) {
-- 
cgit v1.2.3