blob: c356d8fa23a521ee455da1b1bbaf9841caee6a9d [file]
-- Test cases for reference count insertion.
[case testReturnLiteral]
def f() -> int:
return 1
[out]
def f():
r0 :: short_int
L0:
r0 = 1
return r0
[case testReturnLocal]
def f() -> int:
x = 1
return x
[out]
def f():
r0 :: short_int
x :: int
L0:
r0 = 1
x = r0
return x
[case testLocalVars]
def f() -> int:
x = 1
y = x
x = y
return x
[out]
def f():
r0 :: short_int
x, y :: int
L0:
r0 = 1
x = r0
y = x
x = y
return x
[case testLocalVars2]
def f() -> int:
x = 1
y = x
z = x
return y + z
[out]
def f():
r0 :: short_int
x, y, z, r1 :: int
L0:
r0 = 1
x = r0
inc_ref x :: int
y = x
z = x
r1 = CPyTagged_Add(y, z)
dec_ref y :: int
dec_ref z :: int
return r1
[case testFreeAtReturn]
def f() -> int:
x = 1
y = 2
if x == 1:
return x
return y
[out]
def f():
r0 :: short_int
x :: int
r1 :: short_int
y :: int
r2 :: short_int
r3 :: bool
L0:
r0 = 1
x = r0
r1 = 2
y = r1
r2 = 1
r3 = CPyTagged_IsEq(x, r2)
if r3 goto L3 else goto L4 :: bool
L1:
return x
L2:
return y
L3:
dec_ref y :: int
goto L1
L4:
dec_ref x :: int
goto L2
[case testArgumentsInOps]
def f(a: int, b: int) -> int:
x = a + 1
y = x + a
return y
[out]
def f(a, b):
a, b :: int
r0 :: short_int
r1, x, r2, y :: int
L0:
r0 = 1
r1 = CPyTagged_Add(a, r0)
x = r1
r2 = CPyTagged_Add(x, a)
dec_ref x :: int
y = r2
return y
[case testArgumentsInAssign]
def f(a: int) -> int:
x = a
y = a
x = 1
return x + y
[out]
def f(a):
a, x, y :: int
r0 :: short_int
r1 :: int
L0:
inc_ref a :: int
x = a
dec_ref x :: int
inc_ref a :: int
y = a
r0 = 1
x = r0
r1 = CPyTagged_Add(x, y)
dec_ref x :: int
dec_ref y :: int
return r1
[case testAssignToArgument1]
def f(a: int) -> int:
a = 1
y = a
return y
[out]
def f(a):
a :: int
r0 :: short_int
y :: int
L0:
r0 = 1
a = r0
y = a
return y
[case testAssignToArgument2]
def f(a: int) -> int:
a = 1
a = 2
a = 3
return a
[out]
def f(a):
a :: int
r0, r1, r2 :: short_int
L0:
r0 = 1
a = r0
dec_ref a :: int
r1 = 2
a = r1
dec_ref a :: int
r2 = 3
a = r2
return a
[case testAssignToArgument3]
def f(a: int) -> int:
x = 1
a = x
y = x
return a
[out]
def f(a):
a :: int
r0 :: short_int
x, y :: int
L0:
r0 = 1
x = r0
inc_ref x :: int
a = x
y = x
dec_ref y :: int
return a
[case testReturnArgument]
def f(a: int) -> int:
return a
[out]
def f(a):
a :: int
L0:
inc_ref a :: int
return a
[case testConditionalAssignToArgument1]
def f(a: int) -> int:
if a == a:
a = 1
else:
x = 2
y = a + 1
return y
[out]
def f(a):
a :: int
r0 :: bool
r1, r2 :: short_int
x :: int
r3 :: short_int
r4, y :: int
L0:
r0 = CPyTagged_IsEq(a, a)
if r0 goto L1 else goto L2 :: bool
L1:
r1 = 1
a = r1
goto L3
L2:
r2 = 2
x = r2
dec_ref x :: int
goto L4
L3:
r3 = 1
r4 = CPyTagged_Add(a, r3)
dec_ref a :: int
y = r4
return y
L4:
inc_ref a :: int
goto L3
[case testConditionalAssignToArgument2]
def f(a: int) -> int:
if a == a:
x = 2
else:
a = 1
y = a + 1
return y
[out]
def f(a):
a :: int
r0 :: bool
r1 :: short_int
x :: int
r2, r3 :: short_int
r4, y :: int
L0:
r0 = CPyTagged_IsEq(a, a)
if r0 goto L1 else goto L2 :: bool
L1:
r1 = 2
x = r1
dec_ref x :: int
goto L4
L2:
r2 = 1
a = r2
L3:
r3 = 1
r4 = CPyTagged_Add(a, r3)
dec_ref a :: int
y = r4
return y
L4:
inc_ref a :: int
goto L3
[case testConditionalAssignToArgument3]
def f(a: int) -> int:
if a == a:
a = 1
return a
[out]
def f(a):
a :: int
r0 :: bool
r1 :: short_int
L0:
r0 = CPyTagged_IsEq(a, a)
if r0 goto L1 else goto L3 :: bool
L1:
r1 = 1
a = r1
L2:
return a
L3:
inc_ref a :: int
goto L2
[case testAssignRegisterToItself]
def f(a: int) -> int:
a = a
x = 1
x = x
return x + a
-- This is correct but bad code
[out]
def f(a):
a :: int
r0 :: short_int
x, r1 :: int
L0:
inc_ref a :: int
a = a
r0 = 1
x = r0
inc_ref x :: int
dec_ref x :: int
x = x
r1 = CPyTagged_Add(x, a)
dec_ref x :: int
dec_ref a :: int
return r1
[case testIncrement1]
def f(a: int) -> int:
a = a + 1
x = 1
x = x + 1
return a + x
[out]
def f(a):
a :: int
r0 :: short_int
r1 :: int
r2 :: short_int
x :: int
r3 :: short_int
r4, r5 :: int
L0:
r0 = 1
r1 = CPyTagged_Add(a, r0)
a = r1
r2 = 1
x = r2
r3 = 1
r4 = CPyTagged_Add(x, r3)
dec_ref x :: int
x = r4
r5 = CPyTagged_Add(a, x)
dec_ref a :: int
dec_ref x :: int
return r5
[case testIncrement2]
def f() -> None:
x = 1
x = x + 1
[out]
def f():
r0 :: short_int
x :: int
r1 :: short_int
r2 :: int
r3 :: None
L0:
r0 = 1
x = r0
r1 = 1
r2 = CPyTagged_Add(x, r1)
dec_ref x :: int
x = r2
dec_ref x :: int
r3 = None
return r3
[case testAdd1]
def f() -> None:
y = 1
x = y + 1
[out]
def f():
r0 :: short_int
y :: int
r1 :: short_int
r2, x :: int
r3 :: None
L0:
r0 = 1
y = r0
r1 = 1
r2 = CPyTagged_Add(y, r1)
dec_ref y :: int
x = r2
dec_ref x :: int
r3 = None
return r3
[case testAdd2]
def f(a: int) -> int:
a = a + a
x = a
x = x + x
return x
[out]
def f(a):
a, r0, x, r1 :: int
L0:
r0 = CPyTagged_Add(a, a)
a = r0
x = a
r1 = CPyTagged_Add(x, x)
dec_ref x :: int
x = r1
return x
[case testAdd3]
def f(a: int) -> int:
x = a + a
y = x + x
return y
[out]
def f(a):
a, r0, x, r1, y :: int
L0:
r0 = CPyTagged_Add(a, a)
x = r0
r1 = CPyTagged_Add(x, x)
dec_ref x :: int
y = r1
return y
[case testAdd4]
def f(a: int) -> None:
x = a + a
y = 1
z = y + y
[out]
def f(a):
a, r0, x :: int
r1 :: short_int
y, r2, z :: int
r3 :: None
L0:
r0 = CPyTagged_Add(a, a)
x = r0
dec_ref x :: int
r1 = 1
y = r1
r2 = CPyTagged_Add(y, y)
dec_ref y :: int
z = r2
dec_ref z :: int
r3 = None
return r3
[case testAdd5]
def f(a: int) -> None:
a = a + a
x = 1
x = x + x
[out]
def f(a):
a, r0 :: int
r1 :: short_int
x, r2 :: int
r3 :: None
L0:
r0 = CPyTagged_Add(a, a)
a = r0
dec_ref a :: int
r1 = 1
x = r1
r2 = CPyTagged_Add(x, x)
dec_ref x :: int
x = r2
dec_ref x :: int
r3 = None
return r3
[case testReturnInMiddleOfFunction]
def f() -> int:
x = 1
y = 2
z = 3
if z == z:
return z
a = 1
return x + y - a
[out]
def f():
r0 :: short_int
x :: int
r1 :: short_int
y :: int
r2 :: short_int
z :: int
r3 :: bool
r4 :: short_int
a, r5, r6 :: int
L0:
r0 = 1
x = r0
r1 = 2
y = r1
r2 = 3
z = r2
r3 = CPyTagged_IsEq(z, z)
if r3 goto L3 else goto L4 :: bool
L1:
return z
L2:
r4 = 1
a = r4
r5 = CPyTagged_Add(x, y)
dec_ref x :: int
dec_ref y :: int
r6 = CPyTagged_Subtract(r5, a)
dec_ref r5 :: int
dec_ref a :: int
return r6
L3:
dec_ref x :: int
dec_ref y :: int
goto L1
L4:
dec_ref z :: int
goto L2
[case testLoop]
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 :: int
r0 :: short_int
sum :: int
r1 :: short_int
i :: int
r2 :: bool
r3 :: int
r4 :: short_int
r5 :: int
L0:
r0 = 0
sum = r0
r1 = 0
i = r1
L1:
r2 = CPyTagged_IsLe(i, a)
if r2 goto L2 else goto L4 :: bool
L2:
r3 = CPyTagged_Add(sum, i)
dec_ref sum :: int
sum = r3
r4 = 1
r5 = CPyTagged_Add(i, r4)
dec_ref i :: int
i = r5
goto L1
L3:
return sum
L4:
dec_ref i :: int
goto L3
[case testCall]
def f(a: int) -> int:
return f(a + 1)
[out]
def f(a):
a :: int
r0 :: short_int
r1, r2 :: int
L0:
r0 = 1
r1 = CPyTagged_Add(a, r0)
r2 = f(r1)
dec_ref r1 :: int
return r2
[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 testNewList]
def f() -> int:
a = [0, 1]
return 0
[out]
def f():
r0, r1 :: short_int
r2, r3 :: object
r4, a :: list
r5 :: short_int
L0:
r0 = 0
r1 = 1
r2 = box(short_int, r0)
r3 = box(short_int, r1)
r4 = [r2, r3]
a = r4
dec_ref a
r5 = 0
return r5
[case testListSet]
from typing import List
def f(a: List[int], b: List[int]) -> None:
a[0] = b[0]
[out]
def f(a, b):
a, b :: list
r0 :: short_int
r1 :: object
r2 :: int
r3 :: short_int
r4 :: object
r5 :: bool
r6 :: None
L0:
r0 = 0
r1 = CPyList_GetItemShort(b, r0)
r2 = unbox(int, r1)
dec_ref r1
r3 = 0
r4 = box(int, r2)
r5 = CPyList_SetItem(a, r3, r4)
r6 = None
return r6
[case testTupleRefcount]
from typing import Tuple
def f(x: Tuple[Tuple[int, bool], bool]) -> int:
return x[0][0]
[out]
def f(x):
x :: tuple[tuple[int, bool], bool]
r0 :: tuple[int, bool]
r1 :: int
L0:
r0 = x[0]
r1 = r0[0]
dec_ref r0
return r1
[case testUserClassRefCount]
class C:
x: 'C'
def f() -> None:
c = C()
c.x = C()
[out]
def f():
r0, c, r1 :: __main__.C
r2 :: bool
r3 :: None
L0:
r0 = C()
c = r0
r1 = C()
c.x = r1; r2 = is_error
dec_ref c
r3 = None
return r3
[case testCastRefCount]
class C: pass
def f() -> None:
a = [C()]
d = a[0]
[out]
def f():
r0 :: __main__.C
r1, a :: list
r2 :: short_int
r3 :: object
r4, d :: __main__.C
r5 :: None
L0:
r0 = C()
r1 = [r0]
a = r1
r2 = 0
r3 = CPyList_GetItemShort(a, r2)
dec_ref a
r4 = cast(__main__.C, r3)
d = r4
dec_ref d
r5 = None
return r5
[case testUnaryBranchSpecialCase]
def f(x: bool) -> int:
if x:
return 1
return 2
[out]
def f(x):
x :: bool
r0, r1 :: short_int
L0:
if x goto L1 else goto L2 :: bool
L1:
r0 = 1
return r0
L2:
r1 = 2
return r1
[case testUnicodeLiteral]
def f() -> str:
return "some string"
[out]
def f():
r0 :: str
L0:
r0 = unicode_1 :: static ('some string')
inc_ref r0
return r0
[case testPyMethodCall]
def g(x: str) -> int:
return int(x, base=2)
[out]
def g(x):
x :: str
r0 :: short_int
r1 :: object
r2 :: str
r3 :: tuple
r4 :: native_int
r5 :: object
r6 :: dict
r7 :: object
r8 :: int
L0:
r0 = 2
r1 = int
r2 = unicode_1 :: static ('base')
r3 = (x) :: tuple
r4 = 1
r5 = box(short_int, r0)
r6 = CPyDict_Build(r4, r2, r5)
dec_ref r5
r7 = py_call_with_kwargs(r1, r3, r6)
dec_ref r3
dec_ref r6
r8 = unbox(int, r7)
dec_ref r7
return r8
[case testListAppend]
from typing import List
def f(a: List[int], x: int) -> None:
a.append(x)
[out]
def f(a, x):
a :: list
x :: int
r0 :: object
r1 :: bool
r2, r3 :: None
L0:
inc_ref x :: int
r0 = box(int, x)
r1 = a.append(r0) :: list
dec_ref r0
r2 = None
r3 = None
return r3
[case testForDict]
from typing import Dict
def f(d: Dict[int, int]) -> None:
for key in d:
d[key]
[out]
def f(d):
d :: dict
r0, r1 :: short_int
r2 :: int
r3 :: object
r4 :: tuple[bool, int, object]
r5 :: int
r6 :: bool
r7 :: object
key, r8 :: int
r9, r10 :: object
r11 :: int
r12, r13 :: bool
r14 :: None
L0:
r0 = 0
r1 = r0
r2 = len d :: dict
r3 = key_iter d :: dict
L1:
r4 = next_key r3, offset=r1
r5 = r4[1]
r1 = r5
r6 = r4[0]
if r6 goto L2 else goto L6 :: bool
L2:
r7 = r4[2]
dec_ref r4
r8 = unbox(int, r7)
dec_ref r7
key = r8
r9 = box(int, key)
r10 = d[r9] :: dict
dec_ref r9
r11 = unbox(int, r10)
dec_ref r10
dec_ref r11 :: int
L3:
r12 = assert size(d) == r2
goto L1
L4:
r13 = no_err_occurred
L5:
r14 = None
return r14
L6:
dec_ref r2 :: int
dec_ref r3
dec_ref r4
goto L4
[case testBorrowRefs]
def make_garbage(arg: object) -> None:
b = True
while b:
arg = None
b = False
[out]
def make_garbage(arg):
arg :: object
r0, b :: bool
r1 :: None
r2 :: object
r3 :: bool
r4 :: None
L0:
r0 = True
b = r0
L1:
if b goto L2 else goto L3 :: bool
L2:
r1 = None
r2 = box(None, r1)
inc_ref r2
arg = r2
dec_ref arg
r3 = False
b = r3
goto L1
L3:
r4 = None
return r4