diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/l1.kt.0 b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/l1.kt.0 new file mode 100644 index 00000000000..b57eb23fbf4 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/l1.kt.0 @@ -0,0 +1,7 @@ +package lib1 + +abstract class A { + fun foo(): Int = 42 + open fun bar(): Int = 42 + open fun baz(): Int = 42 +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/l1.kt.1 b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/l1.kt.1 new file mode 100644 index 00000000000..2873ec58c00 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/l1.kt.1 @@ -0,0 +1,7 @@ +package lib1 + +abstract class A { + abstract fun foo(): Int + abstract fun bar(): Int + abstract fun baz(): Int +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/module.info b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/module.info new file mode 100644 index 00000000000..1b0feb46a14 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib1/module.info @@ -0,0 +1,12 @@ +STEP 0: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt +STEP 1: + dependencies: stdlib + modifications: + U : l1.kt.1 -> l1.kt +STEP 2: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib2/l2.kt b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib2/l2.kt new file mode 100644 index 00000000000..733b79b357e --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib2/l2.kt @@ -0,0 +1,21 @@ +package lib2 + +import lib1.A + +class B : A() { + override fun baz() = -42 + + val unlinkedFunctionUsage get() = foo() + bar() +} + +class B1 : A() { + override fun baz() = -42 + + val unlinkedFunctionUsage = foo() // Expected failure on class instance initialization. +} + +class B2 : A() { + override fun baz() = -42 + + val unlinkedFunctionUsage = bar() // Expected failure on class instance initialization. +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib2/module.info b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib2/module.info new file mode 100644 index 00000000000..391aab979a6 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/lib2/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/main/m.kt b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/main/m.kt new file mode 100644 index 00000000000..a97d0bc3a76 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/main/m.kt @@ -0,0 +1,81 @@ +import lib1.A +import lib2.B +import lib2.B1 +import lib2.B2 + +fun test1(): String { + val a: A = B() + return try { + val answer: Int = a.foo() // <-- should throw linkage error here + println(answer) + "FAIL1" + } catch (e: Throwable) { + e.checkLinkageError("foo", "B") + } +} + +fun test2(): String { + val a: A = B() + return try { + val answer: Int = a.bar() // <-- should throw linkage error here + println(answer) + "FAIL2" + } catch (e: Throwable) { + e.checkLinkageError("bar", "B") + } +} + +fun test3(): String { + val a: A = B() + val baz = a.baz() + return if (baz == -42) "OK" else "baz=$baz" +} + +fun test4(): String { + val b = B() + return try { + val answer: Int = b.unlinkedFunctionUsage // <-- should throw linkage error here + println(answer) + "FAIL3" + } catch (e: Throwable) { + e.checkLinkageError("foo", "B") + } +} + +fun test5(): String { + return try { + B1() + "FAIL4" + } catch (e: Throwable) { + e.checkLinkageError("foo", "B1") + } +} + +fun test6(): String { + return try { + B2() + "FAIL5" + } catch (e: Throwable) { + e.checkLinkageError("bar", "B2") + } +} + +fun box(): String = checkResults(test1(), test2(), test3(), test4(), test5(), test6()) + +private fun Throwable.checkLinkageError(symbolName: String, className: String): String { + if (this::class.simpleName != "IrLinkageError") return "Unexpected throwable: ${this::class}" + + val expectedMessage = "Abstract function $symbolName is not implemented in non-abstract class $className" + val actualMessage = message.orEmpty() + + return if (expectedMessage == actualMessage) + "OK" + else + "EXPECTED: $expectedMessage, ACTUAL: $actualMessage" +} + +private fun checkResults(vararg results: String): String = when { + results.isEmpty() -> "no results to check" + results.all { it == "OK" } -> "OK" + else -> results.joinToString("\n") +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/main/module.info b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/main/module.info new file mode 100644 index 00000000000..c086bdb447b --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/main/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1, lib2 diff --git a/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/project.info b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/project.info new file mode 100644 index 00000000000..2147306d715 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/project.info @@ -0,0 +1,7 @@ +MODULES: lib1, lib2, main + +STEP 0: + libs: lib1, lib2, main + +STEP 1: + libs: lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/l1.kt.0 b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/l1.kt.0 new file mode 100644 index 00000000000..9319100a46e --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/l1.kt.0 @@ -0,0 +1,6 @@ +package lib1 + +interface A { + fun foo(): Int = 42 + fun bar(): Int = 42 +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/l1.kt.1 b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/l1.kt.1 new file mode 100644 index 00000000000..0e04eaf9bfe --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/l1.kt.1 @@ -0,0 +1,6 @@ +package lib1 + +interface A { + fun foo(): Int + fun bar(): Int +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/module.info b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/module.info new file mode 100644 index 00000000000..1b0feb46a14 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib1/module.info @@ -0,0 +1,12 @@ +STEP 0: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt +STEP 1: + dependencies: stdlib + modifications: + U : l1.kt.1 -> l1.kt +STEP 2: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib2/l2.kt b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib2/l2.kt new file mode 100644 index 00000000000..eb0b51ce193 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib2/l2.kt @@ -0,0 +1,15 @@ +package lib2 + +import lib1.A + +class B : A { + override fun bar() = -42 + + val unlinkedFunctionUsage get() = foo() +} + +class B1 : A { + override fun bar() = -42 + + val unlinkedFunctionUsage = foo() // Expected failure on class instance initialization. +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib2/module.info b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib2/module.info new file mode 100644 index 00000000000..391aab979a6 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/lib2/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/main/m.kt b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/main/m.kt new file mode 100644 index 00000000000..e7891e14279 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/main/m.kt @@ -0,0 +1,60 @@ +import lib1.A +import lib2.B +import lib2.B1 + +fun test1(): String { + val a: A = B() + return try { + val answer: Int = a.foo() // <-- should throw linkage error here + println(answer) + "FAIL1" + } catch(e: Throwable) { + e.checkLinkageError("foo", "B") + } +} + +fun test2(): String { + val a: A = B() + val bar = a.bar() + return if (bar == -42) "OK" else "bar=$bar" +} + +fun test3(): String { + val b = B() + return try { + val answer: Int = b.unlinkedFunctionUsage // <-- should throw linkage error here + println(answer) + "FAIL2" + } catch (e: Throwable) { + e.checkLinkageError("foo", "B") + } +} + +fun test4(): String { + return try { + B1() + "FAIL3" + } catch (e: Throwable) { + e.checkLinkageError("foo", "B1") + } +} + +fun box(): String = checkResults(test1(), test2(), test3(), test4()) + +private fun Throwable.checkLinkageError(symbolName: String, className: String): String { + if (this::class.simpleName != "IrLinkageError") return "Unexpected throwable: ${this::class}" + + val expectedMessage = "Abstract function $symbolName is not implemented in non-abstract class $className" + val actualMessage = message.orEmpty() + + return if (expectedMessage == actualMessage) + "OK" + else + "EXPECTED: $expectedMessage, ACTUAL: $actualMessage" +} + +private fun checkResults(vararg results: String): String = when { + results.isEmpty() -> "no results to check" + results.all { it == "OK" } -> "OK" + else -> results.joinToString("\n") +} diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/main/module.info b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/main/module.info new file mode 100644 index 00000000000..c086bdb447b --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/main/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1, lib2 diff --git a/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/project.info b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/project.info new file mode 100644 index 00000000000..2147306d715 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/project.info @@ -0,0 +1,7 @@ +MODULES: lib1, lib2, main + +STEP 0: + libs: lib1, lib2, main + +STEP 1: + libs: lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/l1.kt.0 b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/l1.kt.0 new file mode 100644 index 00000000000..8de6be7a9e7 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/l1.kt.0 @@ -0,0 +1,10 @@ +package lib1 + +abstract class A { + val foo1: Int = 42 + val foo2: Int get() = 42 + open val bar1: Int = 42 + open val bar2: Int get() = 42 + open val baz1: Int = 42 + open val baz2: Int get() = 42 +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/l1.kt.1 b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/l1.kt.1 new file mode 100644 index 00000000000..1828df6f146 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/l1.kt.1 @@ -0,0 +1,10 @@ +package lib1 + +abstract class A { + abstract val foo1: Int + abstract val foo2: Int + abstract val bar1: Int + abstract val bar2: Int + abstract val baz1: Int + abstract val baz2: Int +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/module.info b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/module.info new file mode 100644 index 00000000000..1b0feb46a14 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib1/module.info @@ -0,0 +1,12 @@ +STEP 0: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt +STEP 1: + dependencies: stdlib + modifications: + U : l1.kt.1 -> l1.kt +STEP 2: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib2/l2.kt b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib2/l2.kt new file mode 100644 index 00000000000..d0eed724263 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib2/l2.kt @@ -0,0 +1,38 @@ +package lib2 + +import lib1.A + +class B : A() { + override val baz1 = -42 + override val baz2 get() = -42 + + val unlinkedPropertyUsage get() = foo1 + foo2 + bar1 + bar2 +} + +class B1 : A() { + override val baz1 = -42 + override val baz2 get() = -42 + + val unlinkedPropertyUsage = foo1 +} + +class B2 : A() { + override val baz1 = -42 + override val baz2 get() = -42 + + val unlinkedPropertyUsage = foo2 +} + +class B3 : A() { + override val baz1 = -42 + override val baz2 get() = -42 + + val unlinkedPropertyUsage = bar1 +} + +class B4 : A() { + override val baz1 = -42 + override val baz2 get() = -42 + + val unlinkedPropertyUsage = bar2 +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib2/module.info b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib2/module.info new file mode 100644 index 00000000000..391aab979a6 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/lib2/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/main/m.kt b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/main/m.kt new file mode 100644 index 00000000000..0190f87058b --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/main/m.kt @@ -0,0 +1,129 @@ +import lib1.A +import lib2.B +import lib2.B1 +import lib2.B2 +import lib2.B3 +import lib2.B4 + +fun test1(): String { + val a: A = B() + return try { + val answer: Int = a.foo1 // <-- should throw linkage error here + println(answer) + "FAIL1" + } catch(e: Throwable) { + e.checkLinkageError("foo1.", "B") + } +} + +fun test2(): String { + val a: A = B() + return try { + val answer: Int = a.foo2 // <-- should throw linkage error here + println(answer) + "FAIL2" + } catch(e: Throwable) { + e.checkLinkageError("foo2.", "B") + } +} + +fun test3(): String { + val a: A = B() + return try { + val answer: Int = a.bar1 // <-- should throw linkage error here + println(answer) + "FAIL1" + } catch(e: Throwable) { + e.checkLinkageError("bar1.", "B") + } +} + +fun test4(): String { + val a: A = B() + return try { + val answer: Int = a.bar2 // <-- should throw linkage error here + println(answer) + "FAIL2" + } catch(e: Throwable) { + e.checkLinkageError("bar2.", "B") + } +} + +fun test5(): String { + val a: A = B() + val baz1 = a.baz1 + return if (baz1 == -42) "OK" else "baz1=$baz1" +} + +fun test6(): String { + val a: A = B() + val baz2 = a.baz2 + return if (baz2 == -42) "OK" else "baz2=$baz2" +} + +fun test7(): String { + val b = B() + return try { + val answer: Int = b.unlinkedPropertyUsage // <-- should throw linkage error here + println(answer) + "FAIL3" + } catch (e: Throwable) { + e.checkLinkageError("foo1.", "B") + } +} + +fun test8(): String { + return try { + B1() + "FAIL4" + } catch (e: Throwable) { + e.checkLinkageError("foo1.", "B1") + } +} + +fun test9(): String { + return try { + B2() + "FAIL5" + } catch (e: Throwable) { + e.checkLinkageError("foo2.", "B2") + } +} + +fun test10(): String { + return try { + B3() + "FAIL6" + } catch (e: Throwable) { + e.checkLinkageError("bar1.", "B3") + } +} + +fun test11(): String { + return try { + B4() + "FAIL7" + } catch (e: Throwable) { + e.checkLinkageError("bar2.", "B4") + } +} + +fun box(): String = checkResults(test1(), test2(), test3(), test4(), test5(), test6(), test7(), test8(), test9(), test10(), test11()) + +private fun Throwable.checkLinkageError(symbolName: String, className: String): String { + if (this::class.simpleName != "IrLinkageError") return "Unexpected throwable: ${this::class}" + + val expectedMessage = "Abstract property accessor $symbolName is not implemented in non-abstract class $className" + val actualMessage = message.orEmpty() + + return if (expectedMessage == actualMessage) + "OK" + else + "EXPECTED: $expectedMessage, ACTUAL: $actualMessage" +} + +private fun checkResults(vararg results: String): String = when { + results.isEmpty() -> "no results to check" + results.all { it == "OK" } -> "OK" + else -> results.joinToString("\n") +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/main/module.info b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/main/module.info new file mode 100644 index 00000000000..c086bdb447b --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/main/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1, lib2 diff --git a/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/project.info b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/project.info new file mode 100644 index 00000000000..2147306d715 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/project.info @@ -0,0 +1,7 @@ +MODULES: lib1, lib2, main + +STEP 0: + libs: lib1, lib2, main + +STEP 1: + libs: lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/l1.kt.0 b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/l1.kt.0 new file mode 100644 index 00000000000..f4045d60bcf --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/l1.kt.0 @@ -0,0 +1,6 @@ +package lib1 + +interface A { + val foo: Int get() = 42 + val bar: Int get() = 42 +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/l1.kt.1 b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/l1.kt.1 new file mode 100644 index 00000000000..bb732268c84 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/l1.kt.1 @@ -0,0 +1,6 @@ +package lib1 + +interface A { + val foo: Int + val bar: Int +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/module.info b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/module.info new file mode 100644 index 00000000000..1b0feb46a14 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib1/module.info @@ -0,0 +1,12 @@ +STEP 0: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt +STEP 1: + dependencies: stdlib + modifications: + U : l1.kt.1 -> l1.kt +STEP 2: + dependencies: stdlib + modifications: + U : l1.kt.0 -> l1.kt diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib2/l2.kt b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib2/l2.kt new file mode 100644 index 00000000000..98590395db9 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib2/l2.kt @@ -0,0 +1,15 @@ +package lib2 + +import lib1.A + +class B : A { + override val bar get() = -42 + + val unlinkedPropertyUsage get() = foo +} + +class B1 : A { + override val bar get() = -42 + + val unlinkedPropertyUsage = foo +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib2/module.info b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib2/module.info new file mode 100644 index 00000000000..391aab979a6 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/lib2/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1 \ No newline at end of file diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/main/m.kt b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/main/m.kt new file mode 100644 index 00000000000..1ae0d0fcd75 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/main/m.kt @@ -0,0 +1,60 @@ +import lib1.A +import lib2.B +import lib2.B1 + +fun test1(): String { + val a: A = B() + return try { + val answer: Int = a.foo // <-- should throw linkage error here + println(answer) + "FAIL" + } catch(e: Throwable) { + e.checkLinkageError("foo.", "B") + } +} + +fun test2(): String { + val a: A = B() + val bar = a.bar + return if (bar == -42) "OK" else "bar=$bar" +} + +fun test3(): String { + val b = B() + return try { + val answer: Int = b.unlinkedPropertyUsage // <-- should throw linkage error here + println(answer) + "FAIL2" + } catch (e: Throwable) { + e.checkLinkageError("foo.", "B") + } +} + +fun test4(): String { + return try { + B1() + "FAIL3" + } catch (e: Throwable) { + e.checkLinkageError("foo.", "B1") + } +} + +fun box(): String = checkResults(test1(), test2(), test3(), test4()) + +private fun Throwable.checkLinkageError(symbolName: String, className: String): String { + if (this::class.simpleName != "IrLinkageError") return "Unexpected throwable: ${this::class}" + + val expectedMessage = "Abstract property accessor $symbolName is not implemented in non-abstract class $className" + val actualMessage = message.orEmpty() + + return if (expectedMessage == actualMessage) + "OK" + else + "EXPECTED: $expectedMessage, ACTUAL: $actualMessage" +} + +private fun checkResults(vararg results: String): String = when { + results.isEmpty() -> "no results to check" + results.all { it == "OK" } -> "OK" + else -> results.joinToString("\n") +} diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/main/module.info b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/main/module.info new file mode 100644 index 00000000000..c086bdb447b --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/main/module.info @@ -0,0 +1,2 @@ +STEP 0: + dependencies: stdlib, lib1, lib2 diff --git a/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/project.info b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/project.info new file mode 100644 index 00000000000..2147306d715 --- /dev/null +++ b/compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/project.info @@ -0,0 +1,7 @@ +MODULES: lib1, lib2, main + +STEP 0: + libs: lib1, lib2, main + +STEP 1: + libs: lib1 \ No newline at end of file diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABINoICTestCaseGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABINoICTestCaseGenerated.java index e65fd20e795..9876a496b0f 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABINoICTestCaseGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABINoICTestCaseGenerated.java @@ -30,6 +30,26 @@ public class JsKLibABINoICTestCaseGenerated extends AbstractJsKLibABINoICTestCas KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/klibABI"), Pattern.compile("^([^_](.+))$"), null, TargetBackend.JS_IR, false); } + @TestMetadata("nonAbstractFunctionInAbstractClassBecomesAbstract") + public void testNonAbstractFunctionInAbstractClassBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/"); + } + + @TestMetadata("nonAbstractFunctionInInterfaceBecomesAbstract") + public void testNonAbstractFunctionInInterfaceBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/"); + } + + @TestMetadata("nonAbstractPropertyInAbstractClassBecomesAbstract") + public void testNonAbstractPropertyInAbstractClassBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/"); + } + + @TestMetadata("nonAbstractPropertyInInterfaceBecomesAbstract") + public void testNonAbstractPropertyInInterfaceBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/"); + } + @TestMetadata("removeAbstractFunctionFromAbstractClass") public void testRemoveAbstractFunctionFromAbstractClass() throws Exception { runTest("compiler/testData/klibABI/removeAbstractFunctionFromAbstractClass/"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABIWithICTestCaseGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABIWithICTestCaseGenerated.java index d202342ac17..3e1208ee54e 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABIWithICTestCaseGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsKLibABIWithICTestCaseGenerated.java @@ -30,6 +30,26 @@ public class JsKLibABIWithICTestCaseGenerated extends AbstractJsKLibABIWithICTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/klibABI"), Pattern.compile("^([^_](.+))$"), null, TargetBackend.JS_IR, false); } + @TestMetadata("nonAbstractFunctionInAbstractClassBecomesAbstract") + public void testNonAbstractFunctionInAbstractClassBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/"); + } + + @TestMetadata("nonAbstractFunctionInInterfaceBecomesAbstract") + public void testNonAbstractFunctionInInterfaceBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/"); + } + + @TestMetadata("nonAbstractPropertyInAbstractClassBecomesAbstract") + public void testNonAbstractPropertyInAbstractClassBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/"); + } + + @TestMetadata("nonAbstractPropertyInInterfaceBecomesAbstract") + public void testNonAbstractPropertyInInterfaceBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/"); + } + @TestMetadata("removeAbstractFunctionFromAbstractClass") public void testRemoveAbstractFunctionFromAbstractClass() throws Exception { runTest("compiler/testData/klibABI/removeAbstractFunctionFromAbstractClass/"); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/KlibABITestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/KlibABITestGenerated.java index da8227bc8f3..ca537f27c0e 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/KlibABITestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/KlibABITestGenerated.java @@ -24,6 +24,30 @@ public class KlibABITestGenerated extends AbstractNativeKlibABITest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/klibABI"), Pattern.compile("^([^_](.+))$"), null, false); } + @Test + @TestMetadata("nonAbstractFunctionInAbstractClassBecomesAbstract") + public void testNonAbstractFunctionInAbstractClassBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractFunctionInAbstractClassBecomesAbstract/"); + } + + @Test + @TestMetadata("nonAbstractFunctionInInterfaceBecomesAbstract") + public void testNonAbstractFunctionInInterfaceBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractFunctionInInterfaceBecomesAbstract/"); + } + + @Test + @TestMetadata("nonAbstractPropertyInAbstractClassBecomesAbstract") + public void testNonAbstractPropertyInAbstractClassBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractPropertyInAbstractClassBecomesAbstract/"); + } + + @Test + @TestMetadata("nonAbstractPropertyInInterfaceBecomesAbstract") + public void testNonAbstractPropertyInInterfaceBecomesAbstract() throws Exception { + runTest("compiler/testData/klibABI/nonAbstractPropertyInInterfaceBecomesAbstract/"); + } + @Test @TestMetadata("removeAbstractFunctionFromAbstractClass") public void testRemoveAbstractFunctionFromAbstractClass() throws Exception {