Fix KT-39548: workaround MinGW bug with .ctors.65534 section (#4249)

This commit is contained in:
SvyatoslavScherbina
2020-07-07 18:19:14 +07:00
committed by GitHub
parent e72793d47b
commit c195ade201
3 changed files with 76 additions and 1 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
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.Name
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 }
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 argList = cValuesOf(priority, ctorFunction, data)
val ctorItem = LLVMConstNamedStruct(kCtorType, argList, 3)!!
+26
View File
@@ -3137,6 +3137,32 @@ task deserialized_listof0(type: KonanLocalTest) {
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") {
goldValue=
"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)
}