From ee10d29a0eeded05ad4fa281c90341412f843d0b Mon Sep 17 00:00:00 2001 From: Shantanu <12621235+hauntsaninja@users.noreply.github.com> Date: Sat, 16 Jul 2022 09:25:38 -0700 Subject: [PATCH] flush keepalives on operator assignment statements (#13144) (#13151) This PR makes mypyc flush keepalives on operator assignment statements, to prevent accessing undefined variables in the generated C code. Fixes mypyc/mypyc#941. Co-authored-by: Zsolt Dollenstein --- mypyc/irbuild/statement.py | 1 + mypyc/test-data/run-generators.test | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/mypyc/irbuild/statement.py b/mypyc/irbuild/statement.py index 93dc5f24158f..c1d9666a34ec 100644 --- a/mypyc/irbuild/statement.py +++ b/mypyc/irbuild/statement.py @@ -136,6 +136,7 @@ def transform_operator_assignment_stmt(builder: IRBuilder, stmt: OperatorAssignm # usually operator assignments are done in-place # but when target doesn't support that we need to manually assign builder.assign(target, res, res.line) + builder.flush_keep_alives() def transform_import(builder: IRBuilder, node: Import) -> None: diff --git a/mypyc/test-data/run-generators.test b/mypyc/test-data/run-generators.test index 8aecce6564c8..8feabd21258b 100644 --- a/mypyc/test-data/run-generators.test +++ b/mypyc/test-data/run-generators.test @@ -595,3 +595,15 @@ class C: self.foo.flag = True yield self.foo.flag = False + +[case testGeneratorEarlyReturnWithBorrows] +from typing import Iterator +class Bar: + bar = 0 +class Foo: + bar = Bar() + def f(self) -> Iterator[int]: + if self: + self.bar.bar += 1 + return + yield 0 \ No newline at end of file