JVM_IR KT-44744 check accessibility of enum entry 'this'

This commit is contained in:
Dmitry Petrov
2021-03-15 12:52:40 +03:00
committed by TeamCityServer
parent 14cb762133
commit e630e00e99
11 changed files with 165 additions and 3 deletions
@@ -5,14 +5,22 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue
import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.isAnonymousObject
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
internal val singletonReferencesPhase = makeIrFilePhase(
@@ -38,7 +46,7 @@ private class SingletonReferencesLowering(val context: JvmBackendContext) : File
override fun visitGetEnumValue(expression: IrGetEnumValue): IrExpression {
val candidate = expression.symbol.owner.correspondingClass
val appropriateThis = thisOfClass(candidate)
return if (candidate != null && appropriateThis != null && !isVisitingSuperConstructor(candidate)) {
return if (candidate != null && appropriateThis != null && isThisAccessible(candidate) && !isVisitingSuperConstructor(candidate)) {
// Replace `SomeEnumClass.SomeEnumEntry` with `this`, if possible.
//
// SomeEnumEntry is a singleton, which is assigned (SETFIELD) to SomeEnumClass after the construction of the singleton is done.
@@ -51,6 +59,25 @@ private class SingletonReferencesLowering(val context: JvmBackendContext) : File
}
}
private fun isThisAccessible(irClass: IrClass): Boolean {
for (scope in allScopes.asReversed()) {
when (val irScopeElement = scope.irElement) {
irClass ->
return true
is IrClass ->
if (!irScopeElement.isInner && !irScopeElement.isAnonymousObject)
return false
is IrField ->
if (irScopeElement.isStatic)
return false
is IrFunction ->
if (irScopeElement.dispatchReceiverParameter == null && irScopeElement.visibility != DescriptorVisibilities.LOCAL)
return false
}
}
return false
}
override fun visitGetObjectValue(expression: IrGetObjectValue): IrExpression {
val instanceField = if (allScopes.any { it.irElement == expression.symbol.owner })
context.cachedDeclarations.getPrivateFieldForObjectInstance(expression.symbol.owner) // Constructor or static method.