-- 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 :: native_int r1, r2, r3 :: bit y, z :: int L0: x = 2 r0 = x & 1 r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: r2 = CPyTagged_IsEq_(x, a) if r2 goto L3 else goto L4 :: bool L2: r3 = x == a if r3 goto L3 else goto L4 :: bool L3: y = 2 goto L5 L4: z = 2 L5: return 1 (0, 0) {a} {a, x} (0, 1) {a, x} {a, x} (0, 2) {a, x} {a, x} (0, 3) {a, x} {a, x} (1, 0) {a, x} {a, x} (1, 1) {a, x} {a, x} (2, 0) {a, x} {a, x} (2, 1) {a, x} {a, x} (3, 0) {a, x} {a, x, y} (3, 1) {a, x, y} {a, x, y} (4, 0) {a, x} {a, x, z} (4, 1) {a, x, z} {a, x, z} (5, 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 = 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 = 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 :: native_int r1, r2, r3 :: bit r4, m :: int L0: L1: r0 = n & 1 r1 = r0 != 0 if r1 goto L2 else goto L3 :: bool L2: r2 = CPyTagged_IsLt_(n, 10) if r2 goto L4 else goto L5 :: bool L3: r3 = n < 10 :: signed if r3 goto L4 else goto L5 :: bool L4: r4 = CPyTagged_Add(n, 2) n = r4 m = n goto L1 L5: return 1 (0, 0) {n} {n} (1, 0) {n} {n} (1, 1) {n} {n} (1, 2) {n} {n} (2, 0) {n} {n} (2, 1) {n} {n} (3, 0) {n} {n} (3, 1) {n} {n} (4, 0) {n} {n} (4, 1) {n} {n} (4, 2) {n} {m, n} (4, 3) {m, n} {m, n} (5, 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 :: native_int r1, r2, r3 :: bit r4 :: native_int r5, r6, r7 :: bit L0: x = 2 y = 2 L1: r0 = n & 1 r1 = r0 != 0 if r1 goto L2 else goto L3 :: bool L2: r2 = CPyTagged_IsLt_(n, 2) if r2 goto L4 else goto L10 :: bool L3: r3 = n < 2 :: signed if r3 goto L4 else goto L10 :: bool L4: n = y L5: r4 = n & 1 r5 = r4 != 0 if r5 goto L6 else goto L7 :: bool L6: r6 = CPyTagged_IsLt_(n, 4) if r6 goto L8 else goto L9 :: bool L7: r7 = n < 4 :: signed if r7 goto L8 else goto L9 :: bool L8: n = 2 n = x goto L5 L9: goto L1 L10: 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} {n, r0, x, y} (1, 1) {n, r0, x, y} {n, r1, x, y} (1, 2) {n, r1, x, y} {n, x, y} (2, 0) {n, x, y} {r2, x, y} (2, 1) {r2, x, y} {x, y} (3, 0) {n, x, y} {r3, x, y} (3, 1) {r3, x, y} {x, y} (4, 0) {x, y} {n, x, y} (4, 1) {n, x, y} {n, x, y} (5, 0) {n, x, y} {n, r4, x, y} (5, 1) {n, r4, x, y} {n, r5, x, y} (5, 2) {n, r5, x, y} {n, x, y} (6, 0) {n, x, y} {n, r6, x, y} (6, 1) {n, r6, x, y} {n, x, y} (7, 0) {n, x, y} {n, r7, x, y} (7, 1) {n, r7, x, y} {n, x, y} (8, 0) {x, y} {x, y} (8, 1) {x, y} {n, x, y} (8, 2) {n, x, y} {n, x, y} (9, 0) {n, x, y} {n, x, y} (10, 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 :: native_int r1 :: bit r2 :: native_int r3, r4, r5 :: bit r6 :: native_int r7 :: bit r8 :: native_int r9, r10, r11 :: bit y, x :: int L0: L1: r0 = a & 1 r1 = r0 != 0 if r1 goto L3 else goto L2 :: bool L2: r2 = a & 1 r3 = r2 != 0 if r3 goto L3 else goto L4 :: bool L3: r4 = CPyTagged_IsLt_(a, a) if r4 goto L5 else goto L12 :: bool L4: r5 = a < a :: signed if r5 goto L5 else goto L12 :: bool L5: L6: r6 = a & 1 r7 = r6 != 0 if r7 goto L8 else goto L7 :: bool L7: r8 = a & 1 r9 = r8 != 0 if r9 goto L8 else goto L9 :: bool L8: r10 = CPyTagged_IsLt_(a, a) if r10 goto L10 else goto L11 :: bool L9: r11 = a < a :: signed if r11 goto L10 else goto L11 :: bool L10: y = a goto L6 L11: x = a goto L1 L12: return 1 (0, 0) {a} {a} (1, 0) {a, x, y} {a, x, y} (1, 1) {a, x, y} {a, x, y} (1, 2) {a, x, y} {a, x, y} (2, 0) {a, x, y} {a, x, y} (2, 1) {a, x, y} {a, x, y} (2, 2) {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} (6, 0) {a, x, y} {a, x, y} (6, 1) {a, x, y} {a, x, y} (6, 2) {a, x, y} {a, x, y} (7, 0) {a, x, y} {a, x, y} (7, 1) {a, x, y} {a, x, y} (7, 2) {a, x, y} {a, x, y} (8, 0) {a, x, y} {a, x, y} (8, 1) {a, x, y} {a, x, y} (9, 0) {a, x, y} {a, x, y} (9, 1) {a, x, y} {a, x, y} (10, 0) {a, x, y} {a, x, y} (10, 1) {a, x, y} {a, x, y} (11, 0) {a, x, y} {a, x, y} (11, 1) {a, x, y} {a, x, y} (12, 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 :: native_int r1, r2, r3 :: bit x :: int L0: r0 = a & 1 r1 = r0 != 0 if r1 goto L1 else goto L2 :: bool L1: r2 = CPyTagged_IsEq_(a, a) if r2 goto L3 else goto L4 :: bool L2: r3 = a == a if r3 goto L3 else goto L4 :: bool L3: x = 4 a = 2 goto L5 L4: x = 2 L5: return x (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} (3, 0) {a} {a} (3, 1) {a} {} (3, 2) {} {} (4, 0) {a} {a} (4, 1) {a} {a} (5, 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 :: native_int r1 :: bit r2 :: native_int r3, r4, r5 :: bit r6, r7 :: int L0: sum = 0 i = 0 L1: r0 = i & 1 r1 = r0 != 0 if r1 goto L3 else goto L2 :: bool L2: r2 = a & 1 r3 = r2 != 0 if r3 goto L3 else goto L4 :: bool L3: r4 = CPyTagged_IsLt_(a, i) if r4 goto L6 else goto L5 :: bool L4: r5 = i <= a :: signed if r5 goto L5 else goto L6 :: bool L5: r6 = CPyTagged_Add(sum, i) sum = r6 r7 = CPyTagged_Add(i, 2) i = r7 goto L1 L6: return sum (0, 0) {a} {a} (0, 1) {a} {a} (0, 2) {a} {a} (1, 0) {a} {a} (1, 1) {a} {a} (1, 2) {a} {a} (2, 0) {a} {a} (2, 1) {a} {a} (2, 2) {a} {a} (3, 0) {a} {a} (3, 1) {a} {a} (4, 0) {a} {a} (4, 1) {a} {a} (5, 0) {a} {a} (5, 1) {a} {a} (5, 2) {a} {a} (5, 3) {a} {a} (5, 4) {a} {a} (6, 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} {}