From cb248253c8f2c16079ffff4cbcbaaca3e2138e4a Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Wed, 17 Aug 2016 16:41:08 +0300 Subject: [PATCH] translator: fix for null return from function --- .../org/kotlinnative/translator/BlockCodegen.kt | 13 +++++++++++-- .../translator/llvm/types/LLVMNullType.kt | 3 +++ .../test/kotlin/tests/input/null_comparison_1.txt | 1 + .../test/kotlin/tests/kotlin/null_comparison_1.kt | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 translator/src/test/kotlin/tests/input/null_comparison_1.txt create mode 100644 translator/src/test/kotlin/tests/kotlin/null_comparison_1.kt diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index b8b51544480..be54cd29da1 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -816,6 +816,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va firstOp.type!!.operatorNeq(firstPointedArgument, secondPointedArgument) } KtTokens.EQ -> { + codeBuilder.addComment("start variable assignment") if (secondOp.type is LLVMNullType) { val result = codeBuilder.getNewVariable(firstOp.type!!, firstOp.pointer) codeBuilder.allocStaticVar(result) @@ -828,6 +829,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va val result = firstOp as LLVMVariable val sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp codeBuilder.storeVariable(result, sourceArgument) + codeBuilder.addComment("end variable assignment") return result } else -> addPrimitiveReferenceOperation(referenceName!!, firstOp, secondNativeOp) @@ -1059,13 +1061,20 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va private fun evaluateReturnInstruction(element: PsiElement, scopeDepth: Int): LLVMVariable? { val next = element.getNextSiblingIgnoringWhitespaceAndComments() - val retVar = evaluateExpression(next, scopeDepth) + var retVar = evaluateExpression(next, scopeDepth) val type = retVar?.type ?: LLVMVoidType() when (type) { is LLVMReferenceType -> genReferenceReturn(retVar!!) - is LLVMVoidType, is LLVMNullType -> { + retVar = when (retVar) { + is LLVMConstant -> LLVMConstant(retVar.value, LLVMNullType(returnType!!.type), returnType!!.pointer - 1) + is LLVMVariable -> LLVMVariable(retVar.label, LLVMNullType(returnType!!.type), retVar.kotlinName, retVar.scope, returnType!!.pointer - 1) + else -> throw IllegalStateException() + } + genReferenceReturn(retVar) + } + is LLVMVoidType -> { codeBuilder.addAnyReturn(LLVMVoidType()) } else -> { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt index 3344ca7e16c..43db966a6ac 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMNullType.kt @@ -16,7 +16,10 @@ class LLVMNullType(var basetype: LLVMType? = null) : LLVMReferred, LLVMType() { return other is LLVMNullType } + override fun parseArg(inputArg: String) = "null" + override fun hashCode() = "null".hashCode() + override fun toString() = basetype?.toString() ?: "" } diff --git a/translator/src/test/kotlin/tests/input/null_comparison_1.txt b/translator/src/test/kotlin/tests/input/null_comparison_1.txt new file mode 100644 index 00000000000..0be278ae353 --- /dev/null +++ b/translator/src/test/kotlin/tests/input/null_comparison_1.txt @@ -0,0 +1 @@ +null_comparison_1() == 87 diff --git a/translator/src/test/kotlin/tests/kotlin/null_comparison_1.kt b/translator/src/test/kotlin/tests/kotlin/null_comparison_1.kt new file mode 100644 index 00000000000..2002c3e0afb --- /dev/null +++ b/translator/src/test/kotlin/tests/kotlin/null_comparison_1.kt @@ -0,0 +1,14 @@ +class null_comparison_1_class + +fun null_comparison_1_getClass(): null_comparison_1_class? { + return null +} + +fun null_comparison_1(): Int { + val a: null_comparison_1_class? = null_comparison_1_getClass() + println(if (a == null) 555 else 9990) + if (a == null) { + return 87 + } + return 945 +} \ No newline at end of file