blob: efd219cc222a3b725c594afef239452c0442df8d [file] [log] [blame]
-- 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 = <error> :: 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 = <error> :: 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} {}