public function testSimpleLoop() { // a = 0; do { a = a + 1 } while (b); c = a; $a = new Variable('a'); $b = new Variable('b'); $c = new Variable('c'); $inst1 = ArithmeticInstruction::newAssignNumberToVariableInstruction($a, 0); $inst2 = new ArithmeticInstruction($a, $a, '+', new Number(1)); $inst3 = new BranchInstruction($b); $inst4 = ArithmeticInstruction::newAssignVariableToVariableInstruction($c, $a); $cfg = new ControlFlowGraph($inst1); $cfg->connectIfNotConnected($inst1, GraphEdge::TYPE_UNCOND, $inst2); $cfg->connectIfNotConnected($inst2, GraphEdge::TYPE_UNCOND, $inst3); $cfg->connectifNotConnected($inst3, GraphEdge::TYPE_ON_TRUE, $inst2); $cfg->connectIfNotConnected($inst3, GraphEdge::TYPE_ON_FALSE, $inst4); $n1 = $cfg->getNode($inst1); $n2 = $cfg->getNode($inst2); $n3 = $cfg->getNode($inst3); $n4 = $cfg->getNode($inst4); $constProp = new DummyConstPropagation($cfg); // This will also show that the framework terminates properly. $constProp->analyze(); // a = 0 is the only thing we know. $this->verifyInHas($n1, $a, null); $this->verifyInHas($n1, $b, null); $this->verifyInHas($n1, $c, null); $this->verifyOutHas($n1, $a, 0); $this->verifyOutHas($n1, $b, null); $this->verifyOutHas($n1, $c, null); // Nothing is provable in this program, so confirm that we haven't // erroneously "proven" something. $this->verifyInHas($n2, $a, null); $this->verifyInHas($n2, $b, null); $this->verifyInHas($n2, $c, null); $this->verifyOutHas($n2, $a, null); $this->verifyOutHas($n2, $b, null); $this->verifyOutHas($n2, $c, null); $this->verifyInHas($n3, $a, null); $this->verifyInHas($n3, $b, null); $this->verifyInHas($n3, $c, null); $this->verifyOutHas($n3, $a, null); $this->verifyOutHas($n3, $b, null); $this->verifyOutHas($n3, $c, null); $this->verifyInHas($n4, $a, null); $this->verifyInHas($n4, $b, null); $this->verifyInHas($n4, $c, null); $this->verifyOutHas($n4, $a, null); $this->verifyOutHas($n4, $b, null); $this->verifyOutHas($n4, $c, null); }