From f3ed006ed9ad3cf163566976b91d42210e16602f Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Thu, 19 Jan 2023 13:26:22 +0100 Subject: [PATCH] Native: add a test for forward declarations with two cinterop libs --- .../backend.native/tests/build.gradle | 19 +++ .../cForwardDeclarationsTwoLibs1.def | 14 ++ .../cForwardDeclarationsTwoLibs2.def | 14 ++ .../forwardDeclarationsTwoLibs.kt | 141 ++++++++++++++++++ .../org/jetbrains/kotlin/KotlinNativeTest.kt | 4 + 5 files changed, 192 insertions(+) create mode 100644 kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs1.def create mode 100644 kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs2.def create mode 100644 kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/forwardDeclarationsTwoLibs.kt diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index ee7fd2f0a76..826a435e447 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -4376,6 +4376,14 @@ createInterop("cForwardDeclarations") { it.defFile "interop/forwardDeclarations/cForwardDeclarations.def" } +createInterop("cForwardDeclarationsTwoLibs1") { + it.defFile "interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs1.def" +} + +createInterop("cForwardDeclarationsTwoLibs2") { + it.defFile "interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs2.def" +} + if (PlatformInfo.isAppleTarget(project)) { createInterop("objcSmoke") { it.defFile 'interop/objc/objcSmoke.def' @@ -4495,7 +4503,9 @@ Task interopTestBase(String name, boolean multiFile, Closure c konanArtifacts { def targetName = target.name def interopLib = task.interop + def interopLib2 = task.interop2 UtilsKt.dependsOnKonanBuildingTask(task, interopLib, target) + if (interopLib2 != null) UtilsKt.dependsOnKonanBuildingTask(task, interopLib2, target) def lib = "lib$name" def hasIntermediateLib = task.lib != null @@ -4504,6 +4514,7 @@ Task interopTestBase(String name, boolean multiFile, Closure c library(lib, targets: [targetName]) { libraries { artifact interopLib + if (interopLib2 != null) artifact interopLib2 } srcFiles task.lib baseDir "$testOutputLocal/$name" @@ -4516,6 +4527,7 @@ Task interopTestBase(String name, boolean multiFile, Closure c program(name, targets: [targetName]) { libraries { artifact interopLib + if (interopLib2 != null) artifact interopLib2 if (hasIntermediateLib) klib lib } @@ -4915,6 +4927,13 @@ interopTest("interop_forwardDeclarations") { interop = "cForwardDeclarations" } +interopTest("interop_forwardDeclarationsTwoLibs") { + disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. + source = "interop/forwardDeclarationsTwoLibs/forwardDeclarationsTwoLibs.kt" + interop = "cForwardDeclarationsTwoLibs1" + interop2 = "cForwardDeclarationsTwoLibs2" +} + /* TODO: This test isn't run automatically task interop_echo_server(type: RunInteropKonanTest) { diff --git a/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs1.def b/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs1.def new file mode 100644 index 00000000000..86d41063e18 --- /dev/null +++ b/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs1.def @@ -0,0 +1,14 @@ +--- +struct StructDeclaredUndeclared; +struct StructDeclaredDeclared; +struct StructDeclaredDefined; +struct StructDefinedUndeclared {}; +struct StructDefinedDeclared {}; +struct StructDefinedDefined {}; + +int use1StructDeclaredUndeclared(struct StructDeclaredUndeclared* declaredUndeclared) { return -3; } +int use1StructDeclaredDeclared(struct StructDeclaredDeclared* declaredDeclared) { return -4; } +int use1StructDeclaredDefined(struct StructDeclaredDefined* declaredDefined) { return -5; } +int use1StructDefinedUndeclared(struct StructDefinedUndeclared* definedUndeclared) { return -6; } +int use1StructDefinedDeclared(struct StructDefinedDeclared* definedDeclared) { return -7; } +int use1StructDefinedDefined(struct StructDefinedDefined* definedDefined) { return -8; } diff --git a/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs2.def b/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs2.def new file mode 100644 index 00000000000..a4397fd9000 --- /dev/null +++ b/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/cForwardDeclarationsTwoLibs2.def @@ -0,0 +1,14 @@ +--- +struct StructUndeclaredDeclared; +struct StructUndeclaredDefined {}; +struct StructDeclaredDeclared; +struct StructDeclaredDefined {}; +struct StructDefinedDeclared; +struct StructDefinedDefined {}; + +int use2StructUndeclaredDeclared(struct StructUndeclaredDeclared* undeclaredDeclared) { return 1; } +int use2StructUndeclaredDefined(struct StructUndeclaredDefined* undeclaredDefined) { return 2; } +int use2StructDeclaredDeclared(struct StructDeclaredDeclared* declaredDeclared) { return 4; } +int use2StructDeclaredDefined(struct StructDeclaredDefined* declaredDefined) { return 5; } +int use2StructDefinedDeclared(struct StructDefinedDeclared* definedDeclared) { return 7; } +int use2StructDefinedDefined(struct StructDefinedDefined* definedDefined) { return 8; } diff --git a/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/forwardDeclarationsTwoLibs.kt b/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/forwardDeclarationsTwoLibs.kt new file mode 100644 index 00000000000..f30119aa429 --- /dev/null +++ b/kotlin-native/backend.native/tests/interop/forwardDeclarationsTwoLibs/forwardDeclarationsTwoLibs.kt @@ -0,0 +1,141 @@ +// This test mostly checks frontend behaviour. + +import cForwardDeclarationsTwoLibs1.* +import cForwardDeclarationsTwoLibs2.* + +// Note: there are no practical cases for this type, but it works in K1 so better to have a test for this. +import cnames.structs.StructUndeclaredUndeclared + +import kotlin.test.assertEquals +import kotlinx.cinterop.COpaque +import kotlinx.cinterop.CStructVar +import kotlinx.cinterop.ptr +// The test should also check that these references can't be resolved, but the test infra doesn't support this yet: +// import cForwardDeclarationsTwoLibs1.StructUndeclaredUndeclared +// import cForwardDeclarationsTwoLibs1.StructUndeclaredDeclared +// import cForwardDeclarationsTwoLibs1.StructUndeclaredDefined +// import cForwardDeclarationsTwoLibs2.StructUndeclaredUndeclared +// import cForwardDeclarationsTwoLibs2.StructDeclaredUndeclared +// import cForwardDeclarationsTwoLibs2.StructDefinedUndeclared + +fun checkSubtype2() {} +fun checkSubtype3() {} +fun checkSubtype4() {} +fun checkSubtype5() {} +fun checkSubtype6() {} + +// Here we rely on frontend reporting conflicting overloads if some of these types turn out to be the same. +fun checkDifferentTypes(s: StructUndeclaredUndeclared?) = 0 +fun checkDifferentTypes(s: StructUndeclaredDeclared?) = 1 +fun checkDifferentTypes(s: StructUndeclaredDefined?) = 2 +fun checkDifferentTypes(s: StructDeclaredUndeclared?) = 3 +fun checkDifferentTypes(s: StructDeclaredDeclared?) = 4 +fun checkDifferentTypes(s: StructDeclaredDefined?) = 5 +fun checkDifferentTypes(s: StructDefinedUndeclared?) = 6 +fun checkDifferentTypes(s: StructDefinedDeclared?) = 7 +fun checkDifferentTypes(s: cForwardDeclarationsTwoLibs1.StructDefinedDefined?) = 8 +fun checkDifferentTypes(s: cForwardDeclarationsTwoLibs2.StructDefinedDefined?) = 9 + +fun main() { + // Checking it is the same type: + checkSubtype3() + checkSubtype2() + + checkSubtype4< + StructUndeclaredDeclared, + cnames.structs.StructUndeclaredDeclared, + cForwardDeclarationsTwoLibs2.StructUndeclaredDeclared, + StructUndeclaredDeclared, + >() + checkSubtype2() + + checkSubtype4< + StructUndeclaredDefined, + cnames.structs.StructUndeclaredDefined, + cForwardDeclarationsTwoLibs2.StructUndeclaredDefined, + StructUndeclaredDefined + >() + checkSubtype2() + + checkSubtype4< + StructDeclaredUndeclared, + cnames.structs.StructDeclaredUndeclared, + cForwardDeclarationsTwoLibs1.StructDeclaredUndeclared, + StructDeclaredUndeclared + >() + checkSubtype2() + + checkSubtype5< + StructDeclaredDeclared, + cnames.structs.StructDeclaredDeclared, + cForwardDeclarationsTwoLibs1.StructDeclaredDeclared, + cForwardDeclarationsTwoLibs2.StructDeclaredDeclared, + StructDeclaredDeclared + >() + checkSubtype2() + + checkSubtype5< + StructDeclaredDefined, + cnames.structs.StructDeclaredDefined, + cForwardDeclarationsTwoLibs1.StructDeclaredDefined, + cForwardDeclarationsTwoLibs2.StructDeclaredDefined, + StructDeclaredDefined + >() + checkSubtype2() + + checkSubtype4< + StructDefinedUndeclared, + cnames.structs.StructDefinedUndeclared, + cForwardDeclarationsTwoLibs1.StructDefinedUndeclared, + StructDefinedUndeclared + >() + checkSubtype2() + + checkSubtype5< + StructDefinedDeclared, + cnames.structs.StructDefinedDeclared, + cForwardDeclarationsTwoLibs1.StructDefinedDeclared, + cForwardDeclarationsTwoLibs2.StructDefinedDeclared, + StructDefinedDeclared + >() + checkSubtype2() + + checkSubtype2() + checkSubtype2() + checkSubtype2() + + val undeclaredUndeclared: StructUndeclaredUndeclared? = null + val undeclaredDeclared: StructUndeclaredDeclared? = null + val undeclaredDefined: StructUndeclaredDefined? = null + val declaredUndeclared: StructDeclaredUndeclared? = null + val declaredDeclared: StructDeclaredDeclared? = null + val declaredDefined: StructDeclaredDefined? = null + val definedUndeclared: StructDefinedUndeclared? = null + val definedDeclared: StructDefinedDeclared? = null + val definedDefined1: cForwardDeclarationsTwoLibs1.StructDefinedDefined? = null + val definedDefined2: cForwardDeclarationsTwoLibs2.StructDefinedDefined? = null + + assertEquals(0, checkDifferentTypes(undeclaredUndeclared)) + assertEquals(1, checkDifferentTypes(undeclaredDeclared)) + assertEquals(2, checkDifferentTypes(undeclaredDefined)) + assertEquals(3, checkDifferentTypes(declaredUndeclared)) + assertEquals(4, checkDifferentTypes(declaredDeclared)) + assertEquals(5, checkDifferentTypes(declaredDefined)) + assertEquals(6, checkDifferentTypes(definedUndeclared)) + assertEquals(7, checkDifferentTypes(definedDeclared)) + assertEquals(8, checkDifferentTypes(definedDefined1)) + assertEquals(9, checkDifferentTypes(definedDefined2)) + + assertEquals(1, use2StructUndeclaredDeclared(undeclaredDeclared?.ptr)) + assertEquals(2, use2StructUndeclaredDefined(undeclaredDefined?.ptr)) + assertEquals(-3, use1StructDeclaredUndeclared(declaredUndeclared?.ptr)) + assertEquals(-4, use1StructDeclaredDeclared(declaredDeclared?.ptr)) + assertEquals(4, use2StructDeclaredDeclared(declaredDeclared?.ptr)) + assertEquals(-5, use1StructDeclaredDefined(declaredDefined?.ptr)) + assertEquals(5, use2StructDeclaredDefined(declaredDefined?.ptr)) + assertEquals(-6, use1StructDefinedUndeclared(definedUndeclared?.ptr)) + assertEquals(-7, use1StructDefinedDeclared(definedDeclared?.ptr)) + assertEquals(7, use2StructDefinedDeclared(definedDeclared?.ptr)) + assertEquals(-8, use1StructDefinedDefined(definedDefined1?.ptr)) + assertEquals(8, use2StructDefinedDefined(definedDefined2?.ptr)) +} diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinNativeTest.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinNativeTest.kt index 62f00947b47..d66d99f2455 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinNativeTest.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/KotlinNativeTest.kt @@ -472,6 +472,10 @@ open class KonanInteropTest : KonanStandaloneTest() { @Input lateinit var interop: String + @Input + @Optional + var interop2: String? = null + @Input @Optional var lib: String? = null