def testContainedIfConflict(self): p = cfg.Program() x = p.NewVariable() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") n3 = n1.ConnectNew("n3") n4 = p.NewCFGNode("n4") n2.ConnectTo(n4) n3.ConnectTo(n4) n5 = n4.ConnectNew("n5") p.entrypoint = n1 x_a = x.AddBinding("a", source_set=[], where=n1) n4.condition = x.AddBinding("b", source_set=[], where=n2) # This is impossible since we have a condition on the way, enforcing x=b. self.assertFalse(n5.HasCombination([x_a]))
def testPasteAtSameNode(self): p = cfg.Program() n1 = p.NewCFGNode("n1") x = p.NewVariable() x.AddBinding("a", source_set=[], where=n1) x.AddBinding("b", source_set=[], where=n1) y = p.NewVariable() y.PasteVariable(x, n1) ay, _ = y.bindings self.assertEqual([v.data for v in x.bindings], ["a", "b"]) self.assertEqual([v.data for v in y.bindings], ["a", "b"]) o, = ay.origins self.assertItemsEqual([set()], o.source_sets) o, = ay.origins self.assertItemsEqual([set()], o.source_sets)
def test_merge_variables(self): p = cfg.Program() n0, n1, n2 = p.NewCFGNode("n0"), p.NewCFGNode("n1"), p.NewCFGNode("n2") u = p.NewVariable() u1 = u.AddBinding(0, source_set=[], where=n0) v = p.NewVariable() v.AddBinding(1, source_set=[], where=n1) v.AddBinding(2, source_set=[], where=n1) w = p.NewVariable() w.AddBinding(1, source_set=[u1], where=n1) w.AddBinding(3, source_set=[], where=n1) vw = cfg_utils.merge_variables(p, n2, [v, w]) six.assertCountEqual(self, vw.data, [1, 2, 3]) val1, = [v for v in vw.bindings if v.data == 1] self.assertTrue(val1.HasSource(u1))
def testSameNodeOrigin(self): # [n1] x = a or b; y = x p = cfg.Program() n1 = p.NewCFGNode("n1") x = p.NewVariable() y = p.NewVariable() xa = x.AddBinding("xa", source_set=[], where=n1) xb = x.AddBinding("xb", source_set=[], where=n1) ya = y.AddBinding("ya", source_set=[xa], where=n1) yb = y.AddBinding("yb", source_set=[xb], where=n1) p.entrypoint = n1 self.assertTrue(n1.HasCombination([xa])) self.assertTrue(n1.HasCombination([xb])) self.assertTrue(n1.HasCombination([xa, ya])) self.assertTrue(n1.HasCombination([xb, yb]))
def testNoNodeOnAllPaths(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") y = p.NewVariable() y1 = y.AddBinding("y", source_set=[], where=n1) n3 = n2.ConnectNew("n3") n4 = n1.ConnectNew("n4") n5 = n4.ConnectNew("n5") n3.ConnectTo(n5) x = p.NewVariable() x1 = x.AddBinding("x", source_set=[], where=n2) n3.condition = x1 n4.condition = x1 self.assertTrue(n5.HasCombination([y1]))
def testProgram(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") u1 = p.NewVariable() u2 = p.NewVariable() a11 = u1.AddBinding(11, source_set=[], where=n1) a12 = u1.AddBinding(12, source_set=[], where=n2) a21 = u2.AddBinding(21, source_set=[], where=n1) a22 = u2.AddBinding(22, source_set=[], where=n2) six.assertCountEqual(self, [n1, n2], p.cfg_nodes) six.assertCountEqual(self, [u1, u2], p.variables) six.assertCountEqual(self, [a11, a21], n1.bindings) six.assertCountEqual(self, [a12, a22], n2.bindings) self.assertEqual(p.next_variable_id, 2)
def testConflictWithCondition(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") z = p.NewVariable() z_a = z.AddBinding("a", source_set=[], where=n1) z_b = z.AddBinding("b", source_set=[], where=n1) n1.condition = z_b goals = [] for _ in range(5): var = p.NewVariable() v = var.AddBinding(".") v.AddOrigin(source_set=[z_a], where=n1) v.AddOrigin(source_set=[z_b], where=n1) goals.append(v) self.assertTrue(n2.HasCombination(goals))
def testConditionsMultiplePaths(self): p = cfg.Program() unreachable_node = p.NewCFGNode("unreachable_node") y = p.NewVariable() unsatisfiable_binding = y.AddBinding("2", source_set=[], where=unreachable_node) n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2", condition=unsatisfiable_binding) n3 = n2.ConnectNew("n3") n4 = n2.ConnectNew("n4") n4.ConnectTo(n3) x = p.NewVariable() b1 = x.AddBinding("1", source_set=[], where=n1) self.assertFalse(n3.HasCombination([b1])) self.assertFalse(n2.HasCombination([b1]))
def testNewVariable(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = p.NewCFGNode("n2") x, y, z = "x", "y", "z" variable = p.NewVariable(bindings=[x, y], source_set=[], where=n1) variable.AddBinding(z, source_set=variable.bindings, where=n2) self.assertSameElements([x, y, z], [v.data for v in variable.bindings]) self.assertTrue(any(len(e.origins) for e in variable.bindings)) # Test that non-list iterables can be passed to NewVariable. v2 = p.NewVariable((x, y), [], n1) self.assertSameElements([x, y], [v.data for v in v2.bindings]) v3 = p.NewVariable({x, y}, [], n1) self.assertSameElements([x, y], [v.data for v in v3.bindings]) v4 = p.NewVariable({x: y}, [], n1) self.assertSameElements([x], [v.data for v in v4.bindings])
def testEmptyBinding(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") x = p.NewVariable() a = x.AddBinding("a") p.entrypoint = n1 self.assertEqual(x.Filter(n1), []) self.assertEqual(x.Filter(n2), []) a.AddOrigin(n2, []) p.entrypoint = n1 self.assertEqual(x.Filter(n1), []) self.assertEqual(x.Filter(n2), [a]) a.AddOrigin(n1, [a]) p.entrypoint = n1 self.assertEqual(x.Filter(n1), [a]) self.assertEqual(x.Filter(n2), [a])
def testHasSource(self): p = cfg.Program() n0, n1, n2 = p.NewCFGNode("n0"), p.NewCFGNode("n1"), p.NewCFGNode("n2") u = p.NewVariable() u1 = u.AddBinding(0, source_set=[], where=n0) v = p.NewVariable() v1 = v.AddBinding(1, source_set=[], where=n1) v2 = v.AddBinding(2, source_set=[u1], where=n1) v3a = v.AddBinding(3, source_set=[], where=n1) v3b = v.AddBinding(3, source_set=[u1], where=n2) self.assertEqual(v3a, v3b) v3 = v3a self.assertTrue(v1.HasSource(v1)) self.assertTrue(v2.HasSource(v2)) self.assertTrue(v3.HasSource(v3)) self.assertFalse(v1.HasSource(u1)) self.assertTrue(v2.HasSource(u1)) self.assertTrue(v3.HasSource(u1))
def testSimpleGraph(self): p = cfg.Program() n1 = p.NewCFGNode("foo") n2 = n1.ConnectNew("n2") n3 = n1.ConnectNew("n3") n4 = n3.ConnectNew("n4") self.assertEqual(0, n1.id) self.assertEqual("foo", n1.name) self.assertEqual(len(n1.outgoing), 2) self.assertEqual(len(n2.outgoing), 0) # pylint: disable=g-generic-assert self.assertEqual(len(n3.outgoing), 1) self.assertEqual(len(n2.incoming), 1) self.assertEqual(len(n3.incoming), 1) self.assertEqual(len(n4.incoming), 1) self.assertIn(n2, n1.outgoing) self.assertIn(n3, n1.outgoing) self.assertIn(n1, n2.incoming) self.assertIn(n1, n3.incoming) self.assertIn(n3, n4.incoming)
def testPasteVariable(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") x = p.NewVariable() ax = x.AddBinding("a", source_set=[], where=n1) bx = x.AddBinding("b", source_set=[], where=n1) y = p.NewVariable() y.PasteVariable(x, n2) ay, by = y.bindings self.assertEqual([v.data for v in x.bindings], ["a", "b"]) self.assertEqual([v.data for v in y.bindings], ["a", "b"]) p.entrypoint = n1 self.assertTrue(n1.HasCombination([ax])) self.assertTrue(n1.HasCombination([bx])) self.assertFalse(n1.HasCombination([ay])) self.assertFalse(n1.HasCombination([by])) self.assertTrue(n2.HasCombination([ay])) self.assertTrue(n2.HasCombination([by]))
def testPrune(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") n3 = n2.ConnectNew("n3") n4 = n3.ConnectNew("n4") n1.ConnectTo(n4) x = p.NewVariable() x.AddBinding(1, [], n1) x.AddBinding(2, [], n2) x.AddBinding(3, [], n3) six.assertCountEqual(self, [1], [v.data for v in x.Bindings(n1)]) six.assertCountEqual(self, [2], [v.data for v in x.Bindings(n2)]) six.assertCountEqual(self, [3], [v.data for v in x.Bindings(n3)]) six.assertCountEqual(self, [1, 3], [v.data for v in x.Bindings(n4)]) six.assertCountEqual(self, [1], x.Data(n1)) six.assertCountEqual(self, [2], x.Data(n2)) six.assertCountEqual(self, [3], x.Data(n3)) six.assertCountEqual(self, [1, 3], x.Data(n4))
def testProgram(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") u1 = p.NewVariable() u2 = p.NewVariable() a11 = u1.AddBinding(11, source_set=[], where=n1) a12 = u1.AddBinding(12, source_set=[], where=n2) a21 = u2.AddBinding(21, source_set=[], where=n1) a22 = u2.AddBinding(22, source_set=[], where=n2) self.assertListEqual(sorted([n1, n2], key=repr), sorted(p.cfg_nodes, key=repr)) self.assertListEqual(sorted([u1, u2], key=repr), sorted(p.variables, key=repr)) self.assertListEqual(sorted([a11, a21], key=repr), sorted(n1.bindings, key=repr)) self.assertListEqual(sorted([a12, a22], key=repr), sorted(n2.bindings, key=repr)) self.assertEqual(p.next_variable_id, 2)
def testConflictingConditionsOnPath(self): # This test case is rather academic - there's no obvious way to construct # a Python program that actually creates the CFG below. p = cfg.Program() x, y, z = p.NewVariable(), p.NewVariable(), p.NewVariable() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") n3 = n1.ConnectNew("n3") n4 = p.NewCFGNode("n4") n2.ConnectTo(n4) n3.ConnectTo(n4) n5 = n4.ConnectNew("n5") n6 = n5.ConnectNew("n6") p.entrypoint = n1 n4.condition = x.AddBinding("a", source_set=[], where=n2) n5.condition = y.AddBinding("a", source_set=[], where=n3) z_a = z.AddBinding("a", source_set=[], where=n1) # Impossible since we can only pass either n2 or n3. self.assertFalse(n6.HasCombination([z_a]))
def testConditionsAreOrdered(self): # The error case in this test is non-deterministic. The test tries to verify # that the list returned by _PathFinder.FindNodeBackwards is ordered from # child to parent. # The error case would be a random order or the reverse order. # To guarantee that this test is working go to FindNodeBackwards and reverse # the order of self._on_path before generating the returned list. p = cfg.Program() n1 = p.NewCFGNode("n1") x1 = p.NewVariable().AddBinding("1", source_set=[], where=n1) n2 = n1.ConnectNew("n2", condition=p.NewVariable().AddBinding( "1", source_set=[], where=n1)) n3 = n2.ConnectNew("n3", condition=p.NewVariable().AddBinding( "1", source_set=[], where=n2)) n4 = n3.ConnectNew("n3", condition=p.NewVariable().AddBinding( "1", source_set=[], where=n3)) # Strictly speaking n1, n2 and n3 would be enough to expose errors. n4 is # added to increase the chance of a failure if the order is random. self.assertTrue(n4.HasCombination([x1]))
def testAssignToNew(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") n3 = n2.ConnectNew("n3") x = p.NewVariable() ax = x.AddBinding("a", source_set=[], where=n1) y = ax.AssignToNewVariable(n2) ay, = y.bindings z = y.AssignToNewVariable(n3) az, = z.bindings self.assertEqual([v.data for v in y.bindings], ["a"]) self.assertEqual([v.data for v in z.bindings], ["a"]) p.entrypoint = n1 self.assertTrue(n1.HasCombination([ax])) self.assertTrue(n2.HasCombination([ax, ay])) self.assertTrue(n3.HasCombination([ax, ay, az])) self.assertFalse(n1.HasCombination([ax, ay])) self.assertFalse(n2.HasCombination([ax, ay, az]))
def testUnordered(self): p = cfg.Program() n0 = p.NewCFGNode("n0") n1 = n0.ConnectNew("n1") x = p.NewVariable() y = p.NewVariable() x0 = x.AddBinding(0, [], n0) x1 = x.AddBinding(1, [], n0) x2 = x.AddBinding(2, [], n0) y0 = y.AddBinding(0, [x0], n1) y1 = y.AddBinding(1, [x1], n1) y2 = y.AddBinding(2, [x2], n1) p.entrypoint = n0 self.assertTrue(explain.Explain([x0], n0)) self.assertTrue(explain.Explain([x1], n0)) self.assertTrue(explain.Explain([x2], n0)) self.assertTrue(explain.Explain([y0], n1)) self.assertTrue(explain.Explain([y1], n1)) self.assertTrue(explain.Explain([y2], n1))
def testCanHaveCombination(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") n3 = n1.ConnectNew("n3") n4 = p.NewCFGNode("n4") n2.ConnectTo(n4) n3.ConnectTo(n4) x = p.NewVariable() y = p.NewVariable() x1 = x.AddBinding("1", source_set=[], where=n2) y2 = y.AddBinding("2", source_set=[], where=n3) self.assertTrue(n4.CanHaveCombination([x1, y2])) self.assertTrue(n4.CanHaveCombination([x1])) self.assertTrue(n4.CanHaveCombination([y2])) self.assertTrue(n3.CanHaveCombination([y2])) self.assertTrue(n2.CanHaveCombination([x1])) self.assertTrue(n1.CanHaveCombination([])) self.assertFalse(n1.CanHaveCombination([x1])) self.assertFalse(n1.CanHaveCombination([y2])) self.assertFalse(n2.CanHaveCombination([x1, y2])) self.assertFalse(n3.CanHaveCombination([x1, y2]))
def testBlockCondition(self): # v1 = x or y or z # node_in # if v1 is x: # node_if # v1 = w # node_block # else: ... # node_else # assert v1 is not x # node_out p = cfg.Program() node_in = p.NewCFGNode("node_in") v1 = p.NewVariable() bx = v1.AddBinding("x", [], node_in) by = v1.AddBinding("y", [], node_in) bz = v1.AddBinding("z", [], node_in) b_if = p.NewVariable().AddBinding("if", [bx], node_in) b_else = b_if.variable.AddBinding("else", [by], node_in) b_else.AddOrigin(node_in, [bz]) node_if = node_in.ConnectNew("node_if", b_if) node_else = node_in.ConnectNew("node_else", b_else) node_block = node_if.ConnectNew("node_block") v1.AddBinding("w", [], node_block) node_out = node_block.ConnectNew("node_out") node_else.ConnectTo(node_out) b_out = p.NewVariable().AddBinding("x", [bx], node_out) self.assertFalse(b_out.IsVisible(node_out))
def testOneStepSimultaneous(self): # Like testSimultaneous, but woven through an additional node # n1->n2->n3 # [n1] x = a or b # [n2] y = x # [n2] z = x p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") x = p.NewVariable() y = p.NewVariable() z = p.NewVariable() a = x.AddBinding("a", source_set=[], where=n1) b = x.AddBinding("b", source_set=[], where=n1) ya = y.AddBinding("ya", source_set=[a], where=n2) yb = y.AddBinding("yb", source_set=[b], where=n2) za = z.AddBinding("za", source_set=[a], where=n2) zb = z.AddBinding("zb", source_set=[b], where=n2) p.entrypoint = n1 self.assertTrue(n2.HasCombination([ya, za])) self.assertTrue(n2.HasCombination([yb, zb])) self.assertFalse(n2.HasCombination([ya, zb])) self.assertFalse(n2.HasCombination([yb, za]))
def testHiddenConflict1(self): p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") n3 = n1.ConnectNew("n3") x = p.NewVariable() y = p.NewVariable() z = p.NewVariable() x_a = x.AddBinding("a", source_set=[], where=n1) x_b = x.AddBinding("b", source_set=[], where=n1) y_a = y.AddBinding("a", source_set=[x_a], where=n1) y_b = y.AddBinding("b", source_set=[x_b], where=n2) z_ab1 = z.AddBinding("ab1", source_set=[x_a, x_b], where=n3) z_ab2 = z.AddBinding("ab2", source_set=[y_a, x_b], where=n3) z_ab3 = z.AddBinding("ab3", source_set=[y_b, x_a], where=n3) z_ab4 = z.AddBinding("ab4", source_set=[y_a, y_b], where=n3) p.entrypoint = n1 self.assertFalse(n2.HasCombination([y_a, x_b])) self.assertFalse(n2.HasCombination([y_b, x_a])) self.assertFalse(n3.HasCombination([z_ab1])) self.assertFalse(n3.HasCombination([z_ab2])) self.assertFalse(n3.HasCombination([z_ab3])) self.assertFalse(n3.HasCombination([z_ab4]))
def testCombinations(self): # n1------->n2 # | | # v v # n3------->n4 # [n2] x = a; y = a # [n3] x = b; y = b p = cfg.Program() n1 = p.NewCFGNode("n1") n2 = n1.ConnectNew("n2") n3 = n1.ConnectNew("n3") n4 = n2.ConnectNew("n4") n3.ConnectTo(n4) x = p.NewVariable() y = p.NewVariable() xa = x.AddBinding("a", source_set=[], where=n2) ya = y.AddBinding("a", source_set=[], where=n2) xb = x.AddBinding("b", source_set=[], where=n3) yb = y.AddBinding("b", source_set=[], where=n3) p.entrypoint = n1 self.assertTrue(n4.HasCombination([xa, ya])) self.assertTrue(n4.HasCombination([xb, yb])) self.assertFalse(n4.HasCombination([xa, yb])) self.assertFalse(n4.HasCombination([xb, ya]))
def testMergeZeroVariables(self): p = cfg.Program() n0 = p.NewCFGNode("n0") self.assertIsInstance(cfg_utils.MergeVariables(p, n0, []), cfg.Variable)
def setUp(self): self.prog = cfg.Program()
def testProgramDefaultData(self): # Basic sanity check to make sure Program.default_data works. p = cfg.Program() self.assertEqual(p.default_data, None) p.default_data = 1 self.assertEqual(p.default_data, 1)
def test_merge_zero_variables(self): p = cfg.Program() n0 = p.NewCFGNode("n0") self.assertIsInstance(cfg_utils.merge_variables(p, n0, []), cfg.Variable)
def setUp(self): super().setUp() self.prog = cfg.Program()
def setUp(self): super().setUp() self.prog = cfg.Program() self.current_location = self.prog.NewCFGNode()