-- Test cases for data flow analysis. [case testSimple_MaybeDefined] def f(a: int) -> None: x = 1 if x == a: y = 1 else: z = 1 [out] def f(a): a, x :: int r0 :: bit y, z :: int L0: x = 2 r0 = int_eq x, a if r0 goto L1 else goto L2 :: bool L1: y = 2 goto L3 L2: z = 2 L3: return 1 (0, 0) {a} {a, x} (0, 1) {a, x} {a, x} (0, 2) {a, x} {a, x} (1, 0) {a, x} {a, x, y} (1, 1) {a, x, y} {a, x, y} (2, 0) {a, x} {a, x, z} (2, 1) {a, x, z} {a, x, z} (3, 0) {a, x, y, z} {a, x, y, z} [case testSimple_Liveness] def f(a: int) -> int: x = 1 if x == 1: return a else: return x [out] def f(a): a, x :: int r0 :: bit L0: x = 2 r0 = int_eq x, 2 if r0 goto L1 else goto L2 :: bool L1: return a L2: return x L3: unreachable (0, 0) {a} {a, x} (0, 1) {a, x} {a, r0, x} (0, 2) {a, r0, x} {a, x} (1, 0) {a} {} (2, 0) {x} {} (3, 0) {} {} [case testSpecial_Liveness] def f() -> int: x = 1 y = 1 x = 2 return x [out] def f(): x, y :: int L0: x = 2 y = 2 x = 4 return x (0, 0) {} {} (0, 1) {} {} (0, 2) {} {x} (0, 3) {x} {} [case testSpecial2_Liveness] def f(a: int) -> int: a = 1 a = 2 a = 3 return a [out] def f(a): a :: int L0: a = 2 a = 4 a = 6 return a (0, 0) {} {} (0, 1) {} {} (0, 2) {} {a} (0, 3) {a} {} [case testSimple_MustDefined] def f(a: int) -> None: if a == 1: y = 1 x = 2 else: x = 2 [out] def f(a): a :: int r0 :: bit y, x :: int L0: r0 = int_eq a, 2 if r0 goto L1 else goto L2 :: bool L1: y = 2 x = 4 goto L3 L2: x = 4 L3: return 1 (0, 0) {a} {a} (0, 1) {a} {a} (1, 0) {a} {a, y} (1, 1) {a, y} {a, x, y} (1, 2) {a, x, y} {a, x, y} (2, 0) {a} {a, x} (2, 1) {a, x} {a, x} (3, 0) {a, x} {a, x} [case testTwoArgs_MustDefined] def f(x: int, y: int) -> int: return x [out] def f(x, y): x, y :: int L0: return x (0, 0) {x, y} {x, y} [case testLoop_MustDefined] def f(n: int) -> None: while n < 5: n = n + 1 m = n [out] def f(n): n :: int r0 :: bit r1, m :: int L0: L1: r0 = int_lt n, 10 if r0 goto L2 else goto L3 :: bool L2: r1 = CPyTagged_Add(n, 2) n = r1 m = n goto L1 L3: return 1 (0, 0) {n} {n} (1, 0) {n} {n} (1, 1) {n} {n} (2, 0) {n} {n} (2, 1) {n} {n} (2, 2) {n} {m, n} (2, 3) {m, n} {m, n} (3, 0) {n} {n} [case testMultiPass_Liveness] def f(n: int) -> None: x = 1 y = 1 while n < 1: n = y while n < 2: n = 1 n = x [out] def f(n): n, x, y :: int r0, r1 :: bit L0: x = 2 y = 2 L1: r0 = int_lt n, 2 if r0 goto L2 else goto L6 :: bool L2: n = y L3: r1 = int_lt n, 4 if r1 goto L4 else goto L5 :: bool L4: n = 2 n = x goto L3 L5: goto L1 L6: return 1 (0, 0) {n} {n, x} (0, 1) {n, x} {n, x, y} (0, 2) {n, x, y} {n, x, y} (1, 0) {n, x, y} {r0, x, y} (1, 1) {r0, x, y} {x, y} (2, 0) {x, y} {n, x, y} (2, 1) {n, x, y} {n, x, y} (3, 0) {n, x, y} {n, r1, x, y} (3, 1) {n, r1, x, y} {n, x, y} (4, 0) {x, y} {x, y} (4, 1) {x, y} {n, x, y} (4, 2) {n, x, y} {n, x, y} (5, 0) {n, x, y} {n, x, y} (6, 0) {} {} [case testCall_Liveness] def f(x: int) -> int: a = f(1) return f(a) + a [out] def f(x): x, r0, a, r1, r2, r3 :: int L0: r0 = f(2) if is_error(r0) goto L3 (error at f:2) else goto L1 L1: a = r0 r1 = f(a) if is_error(r1) goto L3 (error at f:3) else goto L2 L2: r2 = CPyTagged_Add(r1, a) return r2 L3: r3 = :: int return r3 (0, 0) {} {r0} (0, 1) {r0} {r0} (1, 0) {r0} {a} (1, 1) {a} {a, r1} (1, 2) {a, r1} {a, r1} (2, 0) {a, r1} {r2} (2, 1) {r2} {} (3, 0) {} {r3} (3, 1) {r3} {} [case testLoop_MaybeDefined] def f(a: int) -> None: while a < a: while a < a: y = a x = a [out] def f(a): a :: int r0, r1 :: bit y, x :: int L0: L1: r0 = int_lt a, a if r0 goto L2 else goto L6 :: bool L2: L3: r1 = int_lt a, a if r1 goto L4 else goto L5 :: bool L4: y = a goto L3 L5: x = a goto L1 L6: return 1 (0, 0) {a} {a} (1, 0) {a, x, y} {a, x, y} (1, 1) {a, x, y} {a, x, y} (2, 0) {a, x, y} {a, x, y} (3, 0) {a, x, y} {a, x, y} (3, 1) {a, x, y} {a, x, y} (4, 0) {a, x, y} {a, x, y} (4, 1) {a, x, y} {a, x, y} (5, 0) {a, x, y} {a, x, y} (5, 1) {a, x, y} {a, x, y} (6, 0) {a, x, y} {a, x, y} [case testTrivial_BorrowedArgument] def f(a: int, b: int) -> int: return b [out] def f(a, b): a, b :: int L0: return b (0, 0) {a, b} {a, b} [case testSimple_BorrowedArgument] def f(a: int) -> int: b = a a = 1 return a [out] def f(a): a, b :: int L0: b = a a = 2 return a (0, 0) {a} {a} (0, 1) {a} {} (0, 2) {} {} [case testConditional_BorrowedArgument] def f(a: int) -> int: if a == a: x = 2 a = 1 else: x = 1 return x [out] def f(a): a :: int r0 :: bit x :: int L0: r0 = int_eq a, a if r0 goto L1 else goto L2 :: bool L1: x = 4 a = 2 goto L3 L2: x = 2 L3: return x (0, 0) {a} {a} (0, 1) {a} {a} (1, 0) {a} {a} (1, 1) {a} {} (1, 2) {} {} (2, 0) {a} {a} (2, 1) {a} {a} (3, 0) {} {} [case testLoop_BorrowedArgument] def f(a: int) -> int: sum = 0 i = 0 while i <= a: sum = sum + i i = i + 1 return sum [out] def f(a): a, sum, i :: int r0 :: bit r1, r2 :: int L0: sum = 0 i = 0 L1: r0 = int_le i, a if r0 goto L2 else goto L3 :: bool L2: r1 = CPyTagged_Add(sum, i) sum = r1 r2 = CPyTagged_Add(i, 2) i = r2 goto L1 L3: return sum (0, 0) {a} {a} (0, 1) {a} {a} (0, 2) {a} {a} (1, 0) {a} {a} (1, 1) {a} {a} (2, 0) {a} {a} (2, 1) {a} {a} (2, 2) {a} {a} (2, 3) {a} {a} (2, 4) {a} {a} (3, 0) {a} {a} [case testError] def f(x: List[int]) -> None: pass # E: Name "List" is not defined \ # N: Did you forget to import it from "typing"? (Suggestion: "from typing import List") [case testExceptUndefined_Liveness] def lol(x: object) -> int: try: st = id(x) except Exception: return -1 return st + 1 [out] def lol(x): x :: object r0, st :: int r1 :: tuple[object, object, object] r2 :: object r3 :: str r4 :: object r5, r6 :: bit r7, r8 :: int L0: L1: r0 = CPyTagged_Id(x) st = r0 goto L10 L2: r1 = CPy_CatchError() r2 = builtins :: module r3 = 'Exception' r4 = CPyObject_GetAttr(r2, r3) if is_error(r4) goto L8 (error at lol:4) else goto L3 L3: r5 = CPy_ExceptionMatches(r4) if r5 goto L4 else goto L5 :: bool L4: CPy_RestoreExcInfo(r1) return -2 L5: CPy_Reraise() if not 0 goto L8 else goto L6 :: bool L6: unreachable L7: CPy_RestoreExcInfo(r1) goto L10 L8: CPy_RestoreExcInfo(r1) r6 = CPy_KeepPropagating() if not r6 goto L11 else goto L9 :: bool L9: unreachable L10: r7 = CPyTagged_Add(st, 2) return r7 L11: r8 = :: int return r8 (0, 0) {x} {x} (1, 0) {x} {r0} (1, 1) {r0} {st} (1, 2) {st} {st} (2, 0) {} {r1} (2, 1) {r1} {r1, r2} (2, 2) {r1, r2} {r1, r2, r3} (2, 3) {r1, r2, r3} {r1, r4} (2, 4) {r1, r4} {r1, r4} (3, 0) {r1, r4} {r1, r5} (3, 1) {r1, r5} {r1} (4, 0) {r1} {} (4, 1) {} {} (5, 0) {r1} {r1} (5, 1) {r1} {r1} (6, 0) {} {} (7, 0) {r1, st} {st} (7, 1) {st} {st} (8, 0) {r1} {} (8, 1) {} {r6} (8, 2) {r6} {} (9, 0) {} {} (10, 0) {st} {r7} (10, 1) {r7} {} (11, 0) {} {r8} (11, 1) {r8} {}