From 462d2b5123cb5155fc0331bad4fbb076793bd588 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Mon, 26 Dec 2016 17:48:09 +0700 Subject: [PATCH] backend/StaticData: weaken existing global assertion to handle the case when global is used before defined (e.g. kotlin.Unit in stdlib). --- .../kotlin/backend/konan/llvm/StaticData.kt | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt index 7c6f186f282..94f3706a4a2 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticData.kt @@ -14,22 +14,35 @@ internal class StaticData(override val context: Context): ContextUtils { */ class Global private constructor(val staticData: StaticData, val llvmGlobal: LLVMValueRef) { companion object { - fun create(staticData: StaticData, type: LLVMTypeRef, name: String): Global { - val module = staticData.context.llvmModule + private fun createLlvmGlobal(module: LLVMModuleRef, type: LLVMTypeRef, name: String): LLVMValueRef { val isUnnamed = (name == "") // LLVM will select the unique index and represent the global as `@idx`. - if (!isUnnamed && LLVMGetNamedGlobal(module, name) != null) { - throw IllegalArgumentException("Global '$name' already exists") + if (!isUnnamed) { + LLVMGetNamedGlobal(module, name)?.let { existingGlobal -> + if (getGlobalType(existingGlobal) != type || LLVMGetInitializer(existingGlobal) != null) { + throw IllegalArgumentException("Global '$name' already exists") + } else { + return existingGlobal + } + } } val llvmGlobal = LLVMAddGlobal(module, type, name)!! + if (isUnnamed) { // Currently using unnamed globals may result in link errors due to symbol redefinition; // apply the workaround: LLVMSetLinkage(llvmGlobal, LLVMLinkage.LLVMPrivateLinkage) } + return llvmGlobal + } + + fun create(staticData: StaticData, type: LLVMTypeRef, name: String): Global { + val module = staticData.context.llvmModule + + val llvmGlobal = createLlvmGlobal(module!!, type, name) return Global(staticData, llvmGlobal) } }