From 7775b7efd1f3a7eca434710d90368b98198019bd Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 11 Oct 2018 08:36:05 +0200 Subject: [PATCH] Fix wrong heuristic in codegen (#9293) A bare return may trigger the insertion of a genericReset. Fixes #9286 --- compiler/cgen.nim | 8 +++++++- tests/ccgbugs/t9286.nim | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 tests/ccgbugs/t9286.nim diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 918bec0f92..37b07d38dc 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -771,7 +771,13 @@ proc allPathsAsgnResult(n: PNode): InitResultEnum = result = InitRequired of nkReturnStmt: if n.len > 0: - result = allPathsAsgnResult(n[0]) + if n[0].kind == nkEmpty and result != InitSkippable: + # This is a bare `return` statement, if `result` was not initialized + # anywhere else (or if we're not sure about this) let's require it to be + # initialized. This avoids cases like #9286 where this heuristic lead to + # wrong code being generated. + result = InitRequired + else: result = allPathsAsgnResult(n[0]) of nkIfStmt, nkIfExpr: var exhaustive = false result = InitSkippable diff --git a/tests/ccgbugs/t9286.nim b/tests/ccgbugs/t9286.nim new file mode 100644 index 0000000000..8a45a7bf60 --- /dev/null +++ b/tests/ccgbugs/t9286.nim @@ -0,0 +1,22 @@ +discard """ + action: run +""" + +import options +type Foo = ref object + i: int + +proc next(foo: Foo): Option[Foo] = + try: assert(foo.i == 0) + except: return # 2º: none + return some(foo) # 1º: some + +proc test = + let foo = Foo() + var opt = next(foo) # 1º Some + while isSome(opt) and foo.i < 10: + inc(foo.i) + opt = next(foo) # 2º None + assert foo.i == 1, $foo.i + +test()