diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index e332d7ea65d..31e61380f6b 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -41764,6 +41764,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/syntheticAccessors/kt21258_simple.kt"); } + @Test + @TestMetadata("kt48331.kt") + public void testKt48331() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/kt48331.kt"); + } + @Test @TestMetadata("kt9717.kt") public void testKt9717() throws Exception { @@ -41788,12 +41794,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/syntheticAccessors/kt9958Interface.kt"); } + @Test + @TestMetadata("packagePrivate.kt") + public void testPackagePrivate() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/packagePrivate.kt"); + } + @Test @TestMetadata("protectedFromLambda.kt") public void testProtectedFromLambda() throws Exception { runTest("compiler/testData/codegen/box/syntheticAccessors/protectedFromLambda.kt"); } + @Test + @TestMetadata("protectedSuper.kt") + public void testProtectedSuper() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/protectedSuper.kt"); + } + @Test @TestMetadata("protectedSuperclassCompanionObjectMember.kt") public void testProtectedSuperclassCompanionObjectMember() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmCachedDeclarations.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmCachedDeclarations.kt index 23d717d4679..478bb3f7d6b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmCachedDeclarations.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmCachedDeclarations.kt @@ -271,6 +271,9 @@ class JvmCachedDeclarations( parent = irClass overriddenSymbols = fakeOverride.overriddenSymbols copyParameterDeclarationsFrom(fakeOverride) + // The fake override's dispatch receiver has the same type as the real declaration's, + // i.e. some superclass of the current class. This is not good for accessibility checks. + dispatchReceiverParameter?.type = irClass.defaultType annotations = fakeOverride.annotations copyCorrespondingPropertyFrom(fakeOverride) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt index 55ff1ee20c7..e35c7979419 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt @@ -381,7 +381,10 @@ class MethodSignatureMapper(private val context: JvmBackendContext) { internal fun mapToCallableMethod(expression: IrCall, caller: IrFunction?): IrCallableMethod { val callee = expression.symbol.owner val calleeParent = expression.superQualifierSymbol?.owner - ?: expression.dispatchReceiver?.type?.classOrNull?.owner + ?: expression.dispatchReceiver?.type?.classOrNull?.owner?.let { + // Calling Object class methods on interfaces is permitted, but they're not interface methods. + if (it.isJvmInterface && callee.isMethodOfAny()) context.irBuiltIns.anyClass.owner else it + } ?: callee.parentAsClass // Static call or type parameter val owner = typeMapper.mapOwner(calleeParent) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt index 757731b8a07..e12016cfa66 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/AssertionLowering.kt @@ -140,5 +140,8 @@ fun IrClass.buildAssertionsDisabledField(backendContext: JvmBackendContext, topL } } +fun IrField.isAssertionsDisabledField(context: JvmBackendContext) = + name.asString() == ASSERTIONS_DISABLED_FIELD_NAME && type == context.irBuiltIns.booleanType && isStatic + fun IrClass.hasAssertionsDisabledField(context: JvmBackendContext) = - fields.any { it.name.asString() == ASSERTIONS_DISABLED_FIELD_NAME && it.type == context.irBuiltIns.booleanType && it.isStatic } + fields.any { it.isAssertionsDisabledField(context) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt index ea9e12274c1..f7558a7a4a4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt @@ -30,8 +30,6 @@ import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression -import org.jetbrains.kotlin.ir.expressions.IrTypeOperator -import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -239,19 +237,7 @@ private class InterfaceObjectCallsLowering(val context: JvmBackendContext) : IrE if (resolved?.isMethodOfAny() != true) return super.visitCall(expression) val newSuperQualifierSymbol = context.irBuiltIns.anyClass.takeIf { expression.superQualifierSymbol != null } - return super.visitCall(irCall(expression, resolved, newSuperQualifierSymbol = newSuperQualifierSymbol).apply { - dispatchReceiver?.let { receiver -> - val receiverType = resolved.parentAsClass.defaultType - dispatchReceiver = IrTypeOperatorCallImpl( - receiver.startOffset, - receiver.endOffset, - receiverType, - IrTypeOperator.IMPLICIT_CAST, - receiverType, - receiver - ) - } - }) + return super.visitCall(irCall(expression, resolved, newSuperQualifierSymbol = newSuperQualifierSymbol)) } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index e0d16a83bb5..5889c85dceb 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.hasMangledParameters +import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.Modality @@ -34,6 +35,7 @@ import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.org.objectweb.asm.Opcodes internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass { data class LambdaCallSite(val scope: IrDeclaration, val crossinline: Boolean) @@ -232,8 +234,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle // We have a protected member. // It is accessible from a synthetic proxy class (created by LambdaMetafactory) // if it belongs to the current class. - val outerClassInfo = getOuterClassInfo() ?: return false - return outerClassInfo.outerClass == owner.parentAsClass + return getScopeClassOrPackage() == owner.parentAsClass } override fun visitGetField(expression: IrGetField): IrExpression { @@ -707,9 +708,7 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle private fun IrSymbol.isAccessible(withSuper: Boolean, thisObjReference: IrClassSymbol?): Boolean { /// We assume that IR code that reaches us has been checked for correctness at the frontend. /// This function needs to single out those cases where Java accessibility rules differ from Kotlin's. - - val symbolOwner = owner - val declarationRaw = symbolOwner as IrDeclarationWithVisibility + val declarationRaw = owner as IrDeclarationWithVisibility // There is never a problem with visibility of inline functions, as those don't end up as Java entities if (declarationRaw is IrFunction && declarationRaw.isInline) return true @@ -717,85 +716,93 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle // Enum entry constructors are generated as package-private and are accessed only from corresponding enum class if (declarationRaw is IrConstructor && declarationRaw.constructedClass.isEnumEntry) return true - // `internal` maps to public and requires no accessor. - if (!withSuper && !declarationRaw.visibility.isPrivate && !declarationRaw.visibility.isProtected) return true + // Public declarations are already accessible. However, `super` calls are subclass-only. + val jvmVisibility = AsmUtil.getVisibilityAccessFlag(declarationRaw.visibility.delegate) + if (jvmVisibility == Opcodes.ACC_PUBLIC && !withSuper) return true // `toArray` is always accessible cause mapped to public functions - if (symbolOwner is IrSimpleFunction && (symbolOwner.isNonGenericToArray() || symbolOwner.isGenericToArray(context))) { - if (symbolOwner.parentAsClass.isCollectionSubClass) { - return true - } - } + if (declarationRaw is IrSimpleFunction && (declarationRaw.isNonGenericToArray() || declarationRaw.isGenericToArray(context)) && + declarationRaw.parentAsClass.isCollectionSubClass + ) return true - // EnumEntry constructors are always accessible (they are only called from the enclosing Enum class) - if (symbolOwner is IrConstructor && symbolOwner.parentClassOrNull?.isEnumEntry == true) - return true + // `$assertionsDisabled` is accessed only from the same class, even in an inline function + // (the inliner will generate it at the call site if necessary). + if (declarationRaw is IrField && declarationRaw.isAssertionsDisabledField(context)) return true val declaration = when (declarationRaw) { - is IrSimpleFunction -> - declarationRaw.resolveFakeOverride(allowAbstract = true) - ?: declarationRaw - is IrField -> { - val correspondingProperty = declarationRaw.correspondingPropertySymbol?.owner - if (correspondingProperty != null && correspondingProperty.isFakeOverride) { - val realProperty = correspondingProperty.resolveFakeOverride() - ?: throw AssertionError("No real override for ${correspondingProperty.render()}") - realProperty.backingField - ?: throw AssertionError( - "Fake override property ${correspondingProperty.render()} with backing field " + - "overrides a real property with no backing field: ${realProperty.render()}" - ) - } else { - declarationRaw - } - } - else -> - declarationRaw + is IrSimpleFunction -> declarationRaw.resolveFakeOverride(allowAbstract = true)!! + is IrField -> declarationRaw.resolveFakeOverride() + else -> declarationRaw } - // If local variables are accessible by Kotlin rules, they also are by Java rules. - val ownerClass = declaration.parent as? IrClass ?: return true - - val outerClassInfo = getOuterClassInfo() ?: return false - val outerClass = outerClassInfo.outerClass - val throughCrossinlineLambda = outerClassInfo.throughCrossinlineLambda - - val samePackage = ownerClass.getPackageFragment()?.fqName == outerClass.getPackageFragment()?.fqName - val fromSubclassOfReceiversClass = !throughCrossinlineLambda && - outerClass.isSubclassOf(ownerClass) && - (thisObjReference == null || outerClass.symbol.isSubtypeOfClass(thisObjReference)) + val ownerClass = declaration.parent as? IrClass ?: return true // locals are always accessible + val scopeClassOrPackage = getScopeClassOrPackage() ?: return false + val samePackage = ownerClass.getPackageFragment()?.fqName == scopeClassOrPackage.getPackageFragment()?.fqName return when { - declaration.visibility.isPrivate && (throughCrossinlineLambda || ownerClass != outerClass) -> false - declaration.visibility.isProtected && !samePackage && !fromSubclassOfReceiversClass -> false - withSuper && !fromSubclassOfReceiversClass -> false - else -> true + jvmVisibility == 0 /* package only */ -> samePackage + jvmVisibility == Opcodes.ACC_PRIVATE -> ownerClass == scopeClassOrPackage + // JVM `protected`, unlike Kotlin `protected`, permits accesses from the same package. + !withSuper && samePackage -> true + // Super calls and cross-package protected accesses are both only possible from a subclass of the declaration + // owner. Also, the target of a non-static call must be assignable to the current class. This is a verification + // constraint: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.10.1.8 + else -> (scopeClassOrPackage is IrClass && scopeClassOrPackage.isSubclassOf(ownerClass)) && + (thisObjReference == null || thisObjReference.owner.isSubclassOf(scopeClassOrPackage)) } } - private class OuterClassInfo(val outerClass: IrClass, val throughCrossinlineLambda: Boolean) - - private fun getOuterClassInfo(): OuterClassInfo? { - var context = currentScope!!.irElement as IrDeclaration + // Get the class from which all accesses in the current scope will be done after bytecode generation. + // If the current scope is a crossinline lambda, this is not possible, as the lambda maybe inlined + // into some other class; in that case, get at least the package. + private fun getScopeClassOrPackage(): IrDeclarationContainer? { + var context = currentScope?.irElement var throughCrossinlineLambda = false - while (context !is IrClass) { + while (context is IrDeclaration) { val callSite = inlineLambdaToCallSite[context] - if (callSite != null) { - // For inline lambdas, we can navigate to the only call site directly. Crossinline lambdas might be inlined - // into other classes in the same package, so private/super require accessors anyway. - throughCrossinlineLambda = throughCrossinlineLambda || callSite.crossinline - context = callSite.scope - } else if (context is IrFunction && context.isInline) { - // Accesses from inline functions can actually be anywhere; even private inline functions can be - // inlined into a different class, e.g. a callable reference. For protected inline functions - // calling methods on `super` we also need an accessor to satisfy INVOKESPECIAL constraints. - // TODO scan nested classes for calls to private inline functions? - return null - } else { - context = context.parent as? IrDeclaration - ?: return null + when { + // Crossinline lambdas can be inlined into some other class in the same package. However, + // classes within crossinline lambdas should not be regenerated, so if we've already found + // a class *before* reaching this lambda, it's valid: + // class C { + // fun f() {} + // fun g() = inlineFunctionWithCrossinlineArgument { + // f() // this call is done in some unknown class within C's package + // object { val x = f() } // this call is done in C$g$1$1 + // } + // } + callSite != null -> throughCrossinlineLambda = throughCrossinlineLambda || callSite.crossinline + // Inline functions can be inlined into anywhere. Not even private inline functions are safe: + // class C { + // fun f() {} + // private inline fun g1() = f() // `f` is called from C? + // fun g2() = { g1() } // ...or from C$g2$1 in the same package? + // inline fun g3() = g1() // ...or from some other package that calls g3? + // } + // TODO: this has some weird effects for inline functions in local classes, e.g. they + // access the capture fields (package-private) through accessors; this may or may not + // be necessary - local types should in theory not be usable outside the current file. + context is IrFunction && context.isInline -> return null + // TODO: if this class is an object local to an inline function, it could be regenerated, + // so the scope depends on the declaration accessed (see KT-48508): + // class C { + // fun f1() + // inline fun inlineFun() = object { + // fun f2() {} + // fun g1() { + // f1() // this access can be anywhere + // f2() // can pretend this access is from C$foo$1 + // } + // } + // } + // Further complicating things, the accessor for `f1` cannot be in `C$foo$1`, as otherwise + // the accessor itself will be regenerated (and thus not work) at `inlineFun` call sites. + context is IrClass && !throughCrossinlineLambda -> return context } + // Inline lambdas have already been moved out to the containing class, but we still need to check + // the containing function (again, see above), so navigate there instead. + context = callSite?.scope ?: context.parent } - return OuterClassInfo(context, throughCrossinlineLambda) + return context as? IrPackageFragment } // monitorEnter/monitorExit are the only functions which are accessed "illegally" (see kotlin/util/Synchronized.kt). @@ -813,10 +820,18 @@ private fun IrClass.syntheticAccessorToSuperSuffix(): String = // TODO: change this to `fqNameUnsafe.asString().replace(".", "_")` as soon as we're ready to break compatibility with pre-KT-21178 code name.asString().hashCode().toString() -val DescriptorVisibility.isPrivate - get() = DescriptorVisibilities.isPrivate(this) +private fun IrField.resolveFakeOverride(): IrField { + val correspondingProperty = correspondingPropertySymbol?.owner + if (correspondingProperty == null || !correspondingProperty.isFakeOverride) + return this + val realProperty = correspondingProperty.resolveFakeOverride() + ?: throw AssertionError("No real override for ${correspondingProperty.render()}") + return realProperty.backingField + ?: throw AssertionError( + "Fake override property ${correspondingProperty.render()} with backing field " + + "overrides a real property with no backing field: ${realProperty.render()}" + ) +} -val DescriptorVisibility.isProtected - get() = this == DescriptorVisibilities.PROTECTED || - this == JavaDescriptorVisibilities.PROTECTED_AND_PACKAGE || - this == JavaDescriptorVisibilities.PROTECTED_STATIC_VISIBILITY +private val DescriptorVisibility.isProtected + get() = AsmUtil.getVisibilityAccessFlag(delegate) == Opcodes.ACC_PROTECTED diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/indy/LambdaMetafactoryArguments.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/indy/LambdaMetafactoryArguments.kt index 39173ca61da..b395b2f5b35 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/indy/LambdaMetafactoryArguments.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/indy/LambdaMetafactoryArguments.kt @@ -13,8 +13,8 @@ import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound import org.jetbrains.kotlin.backend.jvm.ir.getSingleAbstractMethod import org.jetbrains.kotlin.backend.jvm.ir.isCompiledToJvmDefault import org.jetbrains.kotlin.backend.jvm.lower.findInterfaceImplementation -import org.jetbrains.kotlin.backend.jvm.lower.isPrivate import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity +import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.builders.declarations.buildClass import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter @@ -91,7 +91,7 @@ internal class LambdaMetafactoryArgumentsBuilder( if (implFun.isInline) return null - if (implFun is IrConstructor && implFun.visibility.isPrivate) { + if (implFun is IrConstructor && DescriptorVisibilities.isPrivate(implFun.visibility)) { // Kotlin generates constructor accessors differently from Java. // TODO more precise accessibility check (see SyntheticAccessorLowering::isAccessible) return null diff --git a/compiler/testData/codegen/box/coroutines/javaInterop/objectWithSeveralSuspends.kt b/compiler/testData/codegen/box/coroutines/javaInterop/objectWithSeveralSuspends.kt index e18f4e0f1e9..99b657e016c 100644 --- a/compiler/testData/codegen/box/coroutines/javaInterop/objectWithSeveralSuspends.kt +++ b/compiler/testData/codegen/box/coroutines/javaInterop/objectWithSeveralSuspends.kt @@ -30,10 +30,6 @@ inline fun inlineMe(crossinline c: suspend () -> Unit) = object : SuspendRunnabl StateMachineChecker.suspendHere() StateMachineChecker.suspendHere() } - // TODO: call it from run1 - inline suspend fun inlineMeCapturing() { - c(); c() - } } inline fun inlineMe2(crossinline c: suspend () -> Unit) = inlineMe { c(); c() } diff --git a/compiler/testData/codegen/box/syntheticAccessors/kt48331.kt b/compiler/testData/codegen/box/syntheticAccessors/kt48331.kt new file mode 100644 index 00000000000..d728e3f5123 --- /dev/null +++ b/compiler/testData/codegen/box/syntheticAccessors/kt48331.kt @@ -0,0 +1,25 @@ +// TARGET_BACKEND: JVM +// FILE: foo.kt +package foo + +abstract class Base { + protected abstract fun foo(): String +} + +// FILE: bar.kt +import foo.* + +abstract class C : Base() { + class A : C() { + override fun foo() = "OK" + } + + class B(val x: C) : C() { + // Needs an accessor (`foo` is in another package and `x` is not assignable to `B`) + override fun foo() = x.foo() + + fun bar() = foo() + } +} + +fun box() = C.B(C.A()).bar() diff --git a/compiler/testData/codegen/box/syntheticAccessors/packagePrivate.kt b/compiler/testData/codegen/box/syntheticAccessors/packagePrivate.kt new file mode 100644 index 00000000000..a92fdb5c6fd --- /dev/null +++ b/compiler/testData/codegen/box/syntheticAccessors/packagePrivate.kt @@ -0,0 +1,16 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND: JVM +// FILE: x.kt +package x + +internal class C { + // `foo$default` generated as package-private (not protected): + private fun foo(result: String = "OK") = result + // this needs an accessor: + internal inline fun bar() = foo() +} + +// FILE: y.kt +import x.* + +fun box() = C().bar() diff --git a/compiler/testData/codegen/box/syntheticAccessors/protectedSuper.kt b/compiler/testData/codegen/box/syntheticAccessors/protectedSuper.kt new file mode 100644 index 00000000000..ab6592c6e43 --- /dev/null +++ b/compiler/testData/codegen/box/syntheticAccessors/protectedSuper.kt @@ -0,0 +1,11 @@ +// TARGET_BACKEND: JVM +open class C { + protected open fun foo() = "OK" +} + +class D : C() { + // same package, but `super` needs to be related by class hierarchy: + fun bar() = { super.foo() } +} + +fun box() = D().bar()() diff --git a/compiler/testData/codegen/boxInline/anonymousObject/withInlineMethod.kt b/compiler/testData/codegen/boxInline/anonymousObject/withInlineMethod.kt index 84c5d9d696e..91926ee70ce 100644 --- a/compiler/testData/codegen/boxInline/anonymousObject/withInlineMethod.kt +++ b/compiler/testData/codegen/boxInline/anonymousObject/withInlineMethod.kt @@ -1,3 +1,6 @@ +// IGNORE_BACKEND: JVM, JVM_IR +// IGNORE_BACKEND_FIR: JVM_IR +// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_IR, JVM_MULTI_MODULE_OLD_AGAINST_IR, JVM_MULTI_MODULE_IR_AGAINST_OLD // FILE: 1.kt package test @@ -6,10 +9,9 @@ interface I { } inline fun test(crossinline h: () -> String) = object : I { - // TODO: actually call g() in f() -- currently, the inliner fails to detect - // an inlined read of h's field because it uses a copy of `this` - // as a receiver - override fun f(): String = h() + // TODO: this does not work because the inliner is not correctly remapping the capture. + override fun f(): String = g() + // TODO: and this does not work in JVM_IR because there is a redundant accessor. inline fun g(): String = h() } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 24d4f840d93..87be82f0e90 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -41614,6 +41614,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/syntheticAccessors/kt21258_simple.kt"); } + @Test + @TestMetadata("kt48331.kt") + public void testKt48331() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/kt48331.kt"); + } + @Test @TestMetadata("kt9717.kt") public void testKt9717() throws Exception { @@ -41638,12 +41644,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/syntheticAccessors/kt9958Interface.kt"); } + @Test + @TestMetadata("packagePrivate.kt") + public void testPackagePrivate() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/packagePrivate.kt"); + } + @Test @TestMetadata("protectedFromLambda.kt") public void testProtectedFromLambda() throws Exception { runTest("compiler/testData/codegen/box/syntheticAccessors/protectedFromLambda.kt"); } + @Test + @TestMetadata("protectedSuper.kt") + public void testProtectedSuper() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/protectedSuper.kt"); + } + @Test @TestMetadata("protectedSuperclassCompanionObjectMember.kt") public void testProtectedSuperclassCompanionObjectMember() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 4897e92e245..2c652a8ab88 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -41764,6 +41764,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/syntheticAccessors/kt21258_simple.kt"); } + @Test + @TestMetadata("kt48331.kt") + public void testKt48331() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/kt48331.kt"); + } + @Test @TestMetadata("kt9717.kt") public void testKt9717() throws Exception { @@ -41788,12 +41794,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/syntheticAccessors/kt9958Interface.kt"); } + @Test + @TestMetadata("packagePrivate.kt") + public void testPackagePrivate() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/packagePrivate.kt"); + } + @Test @TestMetadata("protectedFromLambda.kt") public void testProtectedFromLambda() throws Exception { runTest("compiler/testData/codegen/box/syntheticAccessors/protectedFromLambda.kt"); } + @Test + @TestMetadata("protectedSuper.kt") + public void testProtectedSuper() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/protectedSuper.kt"); + } + @Test @TestMetadata("protectedSuperclassCompanionObjectMember.kt") public void testProtectedSuperclassCompanionObjectMember() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 02f0e8fee15..d0d481ef365 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -33390,6 +33390,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class SyntheticAccessors extends AbstractLightAnalysisModeTest { + @TestMetadata("packagePrivate.kt") + public void ignorePackagePrivate() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/packagePrivate.kt"); + } + @TestMetadata("protectedSuperclassCompanionObjectMember.kt") public void ignoreProtectedSuperclassCompanionObjectMember() throws Exception { runTest("compiler/testData/codegen/box/syntheticAccessors/protectedSuperclassCompanionObjectMember.kt"); @@ -33473,6 +33478,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/syntheticAccessors/kt21258_simple.kt"); } + @TestMetadata("kt48331.kt") + public void testKt48331() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/kt48331.kt"); + } + @TestMetadata("kt9717.kt") public void testKt9717() throws Exception { runTest("compiler/testData/codegen/box/syntheticAccessors/kt9717.kt"); @@ -33498,6 +33508,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/syntheticAccessors/protectedFromLambda.kt"); } + @TestMetadata("protectedSuper.kt") + public void testProtectedSuper() throws Exception { + runTest("compiler/testData/codegen/box/syntheticAccessors/protectedSuper.kt"); + } + @TestMetadata("superCallFromMultipleSubclasses.kt") public void testSuperCallFromMultipleSubclasses() throws Exception { runTest("compiler/testData/codegen/box/syntheticAccessors/superCallFromMultipleSubclasses.kt");