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
@@ -14066,6 +14066,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@Test
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@Test
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@Test
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
@@ -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.
+22
View File
@@ -0,0 +1,22 @@
enum class ContentType {
PLAIN_TEXT {
override fun convert(text: String, targetType: ContentType): String {
return text
}
},
MARKDOWN {
override fun convert(text: String, targetType: ContentType): String {
return when (targetType) {
MARKDOWN -> text
PLAIN_TEXT -> ""
}
}
};
abstract fun convert(text: String, targetType: ContentType): String
}
fun box() =
ContentType.PLAIN_TEXT.convert("OK", ContentType.PLAIN_TEXT)
@@ -0,0 +1,27 @@
interface IFoo {
fun foo(e: En): String
}
enum class En {
TEST {
inner class Nested : IFoo {
private val ee = TEST
override fun foo(e: En): String {
return if (e == ee) e.ok else "Failed"
}
}
override val ok: String get() = "OK"
override fun foo(): IFoo = Nested()
},
OTHER {
override val ok: String get() = throw AssertionError()
override fun foo(): IFoo = throw AssertionError()
};
abstract val ok: String
abstract fun foo(): IFoo
}
fun box() = En.TEST.foo().foo(En.TEST)
@@ -14066,6 +14066,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@Test
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@Test
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@Test
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
@@ -14066,6 +14066,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@Test
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@Test
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@Test
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
@@ -11553,6 +11553,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt7257.kt");
@@ -10321,6 +10321,16 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt7257.kt");
@@ -9778,6 +9778,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt7257.kt");
@@ -9778,6 +9778,16 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt7257.kt");
@@ -4797,6 +4797,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/enum/kt38996.kt");
}
@TestMetadata("kt44744.kt")
public void testKt44744() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744.kt");
}
@TestMetadata("kt44744_innerClass.kt")
public void testKt44744_innerClass() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt44744_innerClass.kt");
}
@TestMetadata("kt7257.kt")
public void testKt7257() throws Exception {
runTest("compiler/testData/codegen/box/enum/kt7257.kt");