Fix KT-39548: workaround MinGW bug with .ctors.65534 section (#4249)
This commit is contained in:
committed by
GitHub
parent
e72793d47b
commit
c195ade201
+13
-1
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||||
|
import org.jetbrains.kotlin.konan.target.Family
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||||
@@ -2353,7 +2354,18 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
// Create object { i32, void ()*, i8* } { i32 1, void ()* @ctorFunction, i8* null }
|
// Create object { i32, void ()*, i8* } { i32 1, void ()* @ctorFunction, i8* null }
|
||||||
|
|
||||||
fun createGlobalCtor(ctorFunction: LLVMValueRef): ConstPointer {
|
fun createGlobalCtor(ctorFunction: LLVMValueRef): ConstPointer {
|
||||||
val priority = kImmInt32One
|
val priority = if (context.config.target.family == Family.MINGW) {
|
||||||
|
// Workaround MinGW bug. Using this value makes the compiler generate
|
||||||
|
// '.ctors' section instead of '.ctors.XXXXX', which can't be recognized by ld
|
||||||
|
// when string table is too long.
|
||||||
|
// More details: https://youtrack.jetbrains.com/issue/KT-39548
|
||||||
|
Int32(65535).llvm
|
||||||
|
// Note: this difference in priorities doesn't actually make initializers
|
||||||
|
// platform-dependent, because handling priorities for initializers
|
||||||
|
// from different object files is platform-dependent anyway.
|
||||||
|
} else {
|
||||||
|
kImmInt32One
|
||||||
|
}
|
||||||
val data = kNullInt8Ptr
|
val data = kNullInt8Ptr
|
||||||
val argList = cValuesOf(priority, ctorFunction, data)
|
val argList = cValuesOf(priority, ctorFunction, data)
|
||||||
val ctorItem = LLVMConstNamedStruct(kCtorType, argList, 3)!!
|
val ctorItem = LLVMConstNamedStruct(kCtorType, argList, 3)!!
|
||||||
|
|||||||
@@ -3137,6 +3137,32 @@ task deserialized_listof0(type: KonanLocalTest) {
|
|||||||
source = "serialization/deserialized_listof0.kt"
|
source = "serialization/deserialized_listof0.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task genKt39548 {
|
||||||
|
doFirst {
|
||||||
|
GenTestKT39548Kt.genTestKT39548(file("$buildDir/kt39548/kt39548.kt"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KotlinNativeTestKt.createTest(project, "kt39548", KonanStandaloneTest) { task ->
|
||||||
|
// Test infrastructure doesn't support generated source;
|
||||||
|
// workaround by specifying dummy source:
|
||||||
|
task.source = "does/not/exist/kt39548.dummy.kt"
|
||||||
|
task.enabled = isWindowsTarget(project)
|
||||||
|
|
||||||
|
if (task.enabled) {
|
||||||
|
konanArtifacts {
|
||||||
|
program(name, targets: [target.name]) {
|
||||||
|
baseDir "$testOutputLocal/$name"
|
||||||
|
srcFiles "$buildDir/kt39548/kt39548.kt" // Generated by genKt39548 task.
|
||||||
|
extraOpts task.flags
|
||||||
|
extraOpts project.globalTestArgs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UtilsKt.findKonanBuildTask(project, name, target).dependsOn(genKt39548)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
linkTest("deserialized_members") {
|
linkTest("deserialized_members") {
|
||||||
goldValue=
|
goldValue=
|
||||||
"first level\n"+
|
"first level\n"+
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package org.jetbrains.kotlin
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
fun genTestKT39548(file: File) {
|
||||||
|
val longName = StringBuilder().apply {
|
||||||
|
repeat(10_000_000) {
|
||||||
|
append('a')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val text = """
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
fun $longName(): Int = 42
|
||||||
|
fun <T> same(value: T): T = value
|
||||||
|
val globalInt1: Int = same(1)
|
||||||
|
val globalStringA: String = same("a")
|
||||||
|
@ThreadLocal val threadLocalInt2: Int = same(2)
|
||||||
|
@ThreadLocal val threadLocalStringB: String = same("b")
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
// Ensure function don't get DCEd:
|
||||||
|
val resultOfFunctionWithLongName = $longName()
|
||||||
|
assertEquals(42, resultOfFunctionWithLongName)
|
||||||
|
|
||||||
|
// Check that top-level initializers did run as expected:
|
||||||
|
assertEquals(1, globalInt1)
|
||||||
|
assertEquals("a", globalStringA)
|
||||||
|
assertEquals(2, threadLocalInt2)
|
||||||
|
assertEquals("b", threadLocalStringB)
|
||||||
|
}
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
file.parentFile.mkdirs()
|
||||||
|
file.writeText(text)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user