예제 #1
0
 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]))
예제 #2
0
 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)
예제 #3
0
 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))
예제 #4
0
 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]))
예제 #5
0
 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]))
예제 #6
0
 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)
예제 #7
0
 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))
예제 #8
0
 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]))
예제 #9
0
 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])
예제 #10
0
 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])
예제 #11
0
 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))
예제 #12
0
 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)
예제 #13
0
 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]))
예제 #14
0
 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))
예제 #15
0
 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)
예제 #16
0
 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]))
예제 #17
0
 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]))
예제 #18
0
 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]))
예제 #19
0
 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))
예제 #20
0
 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]))
예제 #21
0
 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))
예제 #22
0
 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]))
예제 #23
0
 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]))
예제 #24
0
 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]))
예제 #25
0
 def testMergeZeroVariables(self):
     p = cfg.Program()
     n0 = p.NewCFGNode("n0")
     self.assertIsInstance(cfg_utils.MergeVariables(p, n0, []),
                           cfg.Variable)
예제 #26
0
 def setUp(self):
   self.prog = cfg.Program()
예제 #27
0
 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)
예제 #28
0
 def test_merge_zero_variables(self):
     p = cfg.Program()
     n0 = p.NewCFGNode("n0")
     self.assertIsInstance(cfg_utils.merge_variables(p, n0, []),
                           cfg.Variable)
예제 #29
0
 def setUp(self):
     super().setUp()
     self.prog = cfg.Program()
예제 #30
0
 def setUp(self):
     super().setUp()
     self.prog = cfg.Program()
     self.current_location = self.prog.NewCFGNode()