[K/N][test] Add test for KT-55776
Tests CFunction invocation type mapping
diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle
index e1f56ab..d8deb35 100644
--- a/kotlin-native/backend.native/tests/build.gradle
+++ b/kotlin-native/backend.native/tests/build.gradle
@@ -513,6 +513,10 @@
useGoldenData = true
}
+task backend_checker_unsupported_type_KT55776(type: KonanLocalTest) {
+ source = "codegen/function/kt55776.kt"
+}
+
task codegen_controlflow_for_loops(type: KonanLocalTest) {
source = "codegen/controlflow/for_loops.kt"
useGoldenData = true
diff --git a/kotlin-native/backend.native/tests/codegen/function/kt55776.kt b/kotlin-native/backend.native/tests/codegen/function/kt55776.kt
new file mode 100644
index 0000000..c4aaadd
--- /dev/null
+++ b/kotlin-native/backend.native/tests/codegen/function/kt55776.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+package codegen.function.kt55776
+
+import kotlinx.cinterop.*
+import kotlin.test.*
+
+// region: KT-55776
+// Checker issues: type T of codegen.function.kt55776.callCFunction of return value is not supported here: doesn't correspond to any C type
+@Suppress("UNCHECKED_CAST")
+fun <T : Number> callCFunction(): T {
+ val cFunction: CPointer<CFunction<() -> T>> = staticCFunction<T> { 42 as T }
+ return cFunction()
+}
+
+@Test
+fun callChecker() {
+ assertEquals(callCFunction(), 42)
+}
+// endregion
+
+// region: Fails with exception in the lowering
+// org.jetbrains.kotlin.backend.konan.lower.InteropTransformer.visitCall(InteropLowering.kt:1113)
+fun <T: Number> getCFun(): CPointer<CFunction<() -> T>> = staticCFunction<T> { 42 as T }
+
+@Test
+fun callChecker2() {
+ assertEquals(getCFun<Int>()(), 42)
+}
+// endregion
+
+// region: Checker issues: type T of codegen.function.kt55776.getCFun2 of callback parameter 1 is not supported here: doesn't correspond to any C type
+@Suppress("UNCHECKED_CAST")
+fun <T: Number> getCFun2(): CPointer<CFunction<(T) -> T>> = staticCFunction<T, T> { _ -> 42 as T }
+
+@Test
+fun callChecker3() {
+ assertEquals(getCFun2<Int>()(13), 42)
+}
+// endregion
+
+// region: Fails with SIGSEGV due to the stack overflow but Cheker doesn't complain
+fun <T: Number> getCFunFromCFun(): CPointer<CFunction<() -> T>> = staticCFunction<CPointer<CFunction<() -> T>>> { getCFunFromCFun<T>() }()
+
+@Test
+fun callChecker4() {
+ getCFunFromCFun<Int>()()
+}
+// endregion
+
+// region: Passes
+fun getF(): CPointer<CFunction<() -> Int>> = staticCFunction<Int> { 42 }
+
+@Suppress("UNCHECKED_CAST")
+fun <T: Number> getCFunFromCFun(): CPointer<CFunction<() -> T>> = getF() as CPointer<CFunction<() -> T>>
+
+@Test
+fun callChecker5() {
+ assertEquals(getCFunFromCFun<Int>()(), 42)
+}
+// endregion
\ No newline at end of file