diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt index 41caac18cd3..9d199c1dc8c 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/linkage/partial/PartiallyLinkedIrTreePatcher.kt @@ -624,7 +624,7 @@ internal class PartiallyLinkedIrTreePatcher( return null // Do the minimal visibility check: Make sure that private declaration is not used outside its declaring entity. - // This should be enough to fix KT-54469 (cases #2 and #3). + // This should be enough to fix KT-54469 (cases #1-#3). val signature = symbol.signature if (signature != null diff --git a/compiler/testData/klibABI/changeClassVisibility/main/m.kt b/compiler/testData/klibABI/changeClassVisibility/main/m.kt index 5631947ec00..2594fc433e0 100644 --- a/compiler/testData/klibABI/changeClassVisibility/main/m.kt +++ b/compiler/testData/klibABI/changeClassVisibility/main/m.kt @@ -8,7 +8,6 @@ fun box() = abiTest { success("PublicTopLevelClass") { PublicTopLevelClass_anyReturnType() } success("PublicTopLevelClass.PublicToInternalNestedClass") { PublicTopLevelClass_PublicToInternalNestedClass_valueParameter(null) } successViaException("PublicTopLevelClass.PublicToInternalNestedClass") { PublicTopLevelClass_PublicToInternalNestedClass_returnType() } - // TODO: KT-54469, creating instance of PublicTopLevelClass.PublicToInternalNestedClass in another module should fail. success("PublicTopLevelClass.PublicToInternalNestedClass") { PublicTopLevelClass_PublicToInternalNestedClass_anyReturnType() } success("PublicTopLevelClass.PublicToProtectedNestedClass") { PublicTopLevelClass_PublicToProtectedNestedClass_valueParameter(null) } successViaException("PublicTopLevelClass.PublicToProtectedNestedClass") { PublicTopLevelClass_PublicToProtectedNestedClass_returnType() } @@ -18,7 +17,6 @@ fun box() = abiTest { inaccessible("PublicToPrivateNestedClass") { PublicTopLevelClass_PublicToPrivateNestedClass_anyReturnType() } success("PublicTopLevelClass.PublicToInternalInnerClass") { PublicTopLevelClass_PublicToInternalInnerClass_valueParameter(null) } successViaException("PublicTopLevelClass.PublicToInternalInnerClass") { PublicTopLevelClass_PublicToInternalInnerClass_returnType() } - // TODO: KT-54469, creating instance of PublicTopLevelClass.PublicToInternalInnerClass in another module should fail. success("PublicTopLevelClass.PublicToInternalInnerClass") { PublicTopLevelClass_PublicToInternalInnerClass_anyReturnType() } success("PublicTopLevelClass.PublicToProtectedInnerClass") { PublicTopLevelClass_PublicToProtectedInnerClass_valueParameter(null) } successViaException("PublicTopLevelClass.PublicToProtectedInnerClass") { PublicTopLevelClass_PublicToProtectedInnerClass_returnType() } @@ -27,7 +25,6 @@ fun box() = abiTest { successViaException("PublicTopLevelClass.PublicToPrivateInnerClass") { PublicTopLevelClass_PublicToPrivateInnerClass_returnType() } inaccessible("PublicToPrivateInnerClass") { PublicTopLevelClass_PublicToPrivateInnerClass_anyReturnType() } - // TODO: KT-54469, accessing PublicToInternalTopLevelClass and all nested classes should fail. success("PublicToInternalTopLevelClass") { PublicToInternalTopLevelClass_valueParameter(null) } successViaException("PublicToInternalTopLevelClass") { PublicToInternalTopLevelClass_returnType() } success("PublicToInternalTopLevelClass") { PublicToInternalTopLevelClass_anyReturnType() } @@ -73,7 +70,6 @@ fun box() = abiTest { unlinkedConstructorSymbol("/PublicToPrivateTopLevelClass.") { PublicToPrivateTopLevelClass_PublicToPrivateInnerClass_anyReturnType() } success("PublicTopLevelClassInheritor") { PublicTopLevelClassInheritor() } - // TODO: KT-54469, creating instance of PublicToInternalTopLevelClassInheritor should fail. success("PublicToInternalTopLevelClassInheritor") { PublicToInternalTopLevelClassInheritor() } expectFailure(linkage("Constructor 'PublicToPrivateTopLevelClassInheritor.' can not be called: Class 'PublicToPrivateTopLevelClassInheritor' uses unlinked class symbol '/PublicToPrivateTopLevelClass'")) { PublicToPrivateTopLevelClassInheritor() } } diff --git a/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt b/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt index 10067340fa8..1cb093aeaac 100644 --- a/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt +++ b/compiler/testData/klibABI/changeFunctionVisibility/main/m.kt @@ -8,14 +8,12 @@ fun box() = abiTest { success("publicToInternalTopLevelFunction.v2") { publicToInternalTopLevelFunction() } // Signature remains the same. success("publicToInternalPATopLevelFunction.v2") { publicToInternalPATopLevelFunction() } // Signature remains the same. - unlinkedSymbol("/publicToPrivateTopLevelFunction") { publicToPrivateTopLevelFunction() } // Signature changed. + unlinkedTopLevelPrivateSymbol("/publicToPrivateTopLevelFunction") { publicToPrivateTopLevelFunction() } // Signature changed. success("Container.publicToProtectedFunction.v2") { c.publicToProtectedFunction() } // Signature remains the same. success("Container.publicToProtectedFunction.v2") { ci.publicToProtectedFunction() } // Signature remains the same. - // TODO: KT-54469, Container.publicToInternalFunction() should fail because it is accessed from another module. success("Container.publicToInternalFunction.v2") { c.publicToInternalFunction() } // Signature remains the same. unlinkedSymbol("/ContainerImpl.publicToInternalFunction") { ci.publicToInternalFunction() } // FOs are not generated for internal members from other module. - // TODO: KT-54469, Container.publicToInternalPAFunction() should fail because it is accessed from another module. success("Container.publicToInternalPAFunction.v2") { c.publicToInternalPAFunction() } // Signature remains the same. unlinkedSymbol("/ContainerImpl.publicToInternalPAFunction") { ci.publicToInternalPAFunction() } // FOs are not generated for internal members from other module. inaccessible("publicToPrivateFunction") { c.publicToPrivateFunction() } // Inaccessible from other module though signature remains the same. @@ -59,6 +57,14 @@ private inline fun TestBuilder.unlinkedSymbol(signature: String, noinline block: expectFailure(linkage("Function '$functionName' can not be called: No function found for symbol '$signature'"), block) } +private inline fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, noinline block: () -> Unit) { + if (testMode == NATIVE_CACHE_STATIC_EVERYWHERE) { + val functionName = signature.removePrefix("/").substringAfterLast(".") + expectFailure(linkage("Function '$functionName' can not be called: Private function declared in module can not be accessed in module
"), block) + } else + unlinkedSymbol(signature, block) +} + private inline fun TestBuilder.inaccessible(functionName: String, noinline block: () -> Unit) = expectFailure( linkage("Function '$functionName' can not be called: Private function declared in module can not be accessed in module
"), block diff --git a/compiler/testData/klibABI/changePropertyVisibility/main/m.kt b/compiler/testData/klibABI/changePropertyVisibility/main/m.kt index 5162ed953c7..afbd96e9315 100644 --- a/compiler/testData/klibABI/changePropertyVisibility/main/m.kt +++ b/compiler/testData/klibABI/changePropertyVisibility/main/m.kt @@ -10,23 +10,19 @@ fun box() = abiTest { success("publicToInternalTopLevelProperty2.v2") { publicToInternalTopLevelProperty2 } // Signature remains the same. success("publicToInternalPATopLevelProperty1.v2") { publicToInternalPATopLevelProperty1 } // Signature remains the same. success("publicToInternalPATopLevelProperty2.v2") { publicToInternalPATopLevelProperty2 } // Signature remains the same. - unlinkedSymbol("/publicToPrivateTopLevelProperty1.") { publicToPrivateTopLevelProperty1 } // Signature changed. - unlinkedSymbol("/publicToPrivateTopLevelProperty2.") { publicToPrivateTopLevelProperty2 } // Signature changed. + unlinkedTopLevelPrivateSymbol("/publicToPrivateTopLevelProperty1.") { publicToPrivateTopLevelProperty1 } // Signature changed. + unlinkedTopLevelPrivateSymbol("/publicToPrivateTopLevelProperty2.") { publicToPrivateTopLevelProperty2 } // Signature changed. success("Container.publicToProtectedProperty1.v2") { c.publicToProtectedProperty1 } // Signature remains the same. success("Container.publicToProtectedProperty1.v2") { ci.publicToProtectedProperty1 } // Signature remains the same. success("Container.publicToProtectedProperty2.v2") { c.publicToProtectedProperty2 } // Signature remains the same. success("Container.publicToProtectedProperty2.v2") { ci.publicToProtectedProperty2 } // Signature remains the same. - // TODO: KT-54469, Container.publicToInternalProperty1 should fail because it is accessed from another module. success("Container.publicToInternalProperty1.v2") { c.publicToInternalProperty1 } // Signature remains the same. unlinkedSymbol("/ContainerImpl.publicToInternalProperty1.") { ci.publicToInternalProperty1 } // FOs are not generated for internal members from other module. - // TODO: KT-54469, Container.publicToInternalProperty2 should fail because it is accessed from another module. success("Container.publicToInternalProperty2.v2") { c.publicToInternalProperty2 } // Signature remains the same. unlinkedSymbol("/ContainerImpl.publicToInternalProperty2.") { ci.publicToInternalProperty2 } // FOs are not generated for internal members from other module. - // TODO: KT-54469, Container.publicToInternalPAProperty1 should fail because it is accessed from another module. success("Container.publicToInternalPAProperty1.v2") { c.publicToInternalPAProperty1 } // Signature remains the same. unlinkedSymbol("/ContainerImpl.publicToInternalPAProperty1.") { ci.publicToInternalPAProperty1 } // FOs are not generated for internal members from other module. - // TODO: KT-54469, Container.publicToInternalPAProperty2 should fail because it is accessed from another module. success("Container.publicToInternalPAProperty2.v2") { c.publicToInternalPAProperty2 } // Signature remains the same. unlinkedSymbol("/ContainerImpl.publicToInternalPAProperty2.") { ci.publicToInternalPAProperty2 } // FOs are not generated for internal members from other module. inaccessible("publicToPrivateProperty1.") { c.publicToPrivateProperty1 } // Inaccessible from other module though signature remains the same. @@ -127,6 +123,14 @@ private inline fun TestBuilder.unlinkedSymbol(signature: String, noinline block: expectFailure(linkage("Property accessor '$accessorName' can not be called: No property accessor found for symbol '$signature'"), block) } +private inline fun TestBuilder.unlinkedTopLevelPrivateSymbol(signature: String, noinline block: () -> Unit) { + if (testMode == NATIVE_CACHE_STATIC_EVERYWHERE) { + val accessorName = signature.removePrefix("/").split('.').takeLast(2).joinToString(".") + expectFailure(linkage("Property accessor '$accessorName' can not be called: Private property accessor declared in module can not be accessed in module
"), block) + } else + unlinkedSymbol(signature, block) +} + private inline fun TestBuilder.inaccessible(accessorName: String, noinline block: () -> Unit) = expectFailure( linkage("Property accessor '$accessorName' can not be called: Private property accessor declared in module can not be accessed in module
"), block diff --git a/compiler/testData/klibABI/classTransformations/lib2/l2.kt b/compiler/testData/klibABI/classTransformations/lib2/l2.kt index b6607b3bda3..317093e6860 100644 --- a/compiler/testData/klibABI/classTransformations/lib2/l2.kt +++ b/compiler/testData/klibABI/classTransformations/lib2/l2.kt @@ -242,3 +242,16 @@ enum class StableEnum { abstract val test: String } +// This is required to check that the guard condition initially added in commit +// https://github.com/JetBrains/kotlin/blob/2a4d8800374578c1aa9ec9c996b393a98f5a6e3b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt#L701 +// does not break Native codegen anymore. +class StableInheritorOfClassThatUsesPrivateTopLevelClass : AbstractIterator() { + private var i = 0 + public override fun computeNext() { + if (i < 5) setNext((i++).toString()) else done() + } +} + +fun testStableInheritorOfClassThatUsesPrivateTopLevelClass(): String = buildString { + for (s in StableInheritorOfClassThatUsesPrivateTopLevelClass()) append(s) +} diff --git a/compiler/testData/klibABI/classTransformations/main/m.kt b/compiler/testData/klibABI/classTransformations/main/m.kt index 35946b1a184..d7830f27100 100644 --- a/compiler/testData/klibABI/classTransformations/main/m.kt +++ b/compiler/testData/klibABI/classTransformations/main/m.kt @@ -210,4 +210,6 @@ fun box() = abiTest { expectSuccess { StableEnum.FOO.test } expectSuccess { StableEnum.BAR.test } + + expectSuccess("01234") { testStableInheritorOfClassThatUsesPrivateTopLevelClass() } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt index 5f0a0b12a41..16f378fd833 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/serialization/KonanIrlinker.kt @@ -698,13 +698,6 @@ internal class KonanIrLinker( deserializedSymbols[idSig]?.let { return it } val descriptor = descriptorByIdSignatureFinder.findDescriptorBySignature(idSig) ?: return null - if (partialLinkageSupport.isEnabled - && descriptor.isTopLevelInPackage() - && (descriptor as? DeclarationDescriptorWithVisibility)?.visibility == DescriptorVisibilities.PRIVATE - && with(KonanManglerDesc) { !descriptor.isPlatformSpecificExport() } - ) { - return null // Fixes case #1 in KT-54469 - } descriptorSignatures[descriptor] = idSig