JVM_IR: try to fix SyntheticAccessorLowering.isAccessible again

The condition on the relationship between the current class and the type
of the receiver for protected members was the opposite of what the JVMS
says, and yet somehow mostly worked?

 #KT-48331 Fixed
 #KT-20542 Fixed
This commit is contained in:
pyos
2021-08-23 13:48:23 +02:00
committed by TeamCityServer
parent 9a472c418f
commit 7ce5556de3
15 changed files with 231 additions and 102 deletions
@@ -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 {
@@ -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)
}
@@ -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)
@@ -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) }
@@ -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))
}
}
@@ -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
@@ -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
@@ -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() }
@@ -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()
@@ -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()
@@ -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()()
@@ -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()
}
@@ -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 {
@@ -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 {
@@ -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");