Fix for KT-10729: Accessing private const field in companion object from a function in the same companion generates run-time error
This commit is contained in:
@@ -2119,7 +2119,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
|
FieldAccessorKind fieldAccessorKind = FieldAccessorKind.NORMAL;
|
||||||
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||||
if (isBackingFieldInClassCompanion && forceField) {
|
if (isBackingFieldInClassCompanion && (forceField || propertyDescriptor.isConst() && Visibilities.isPrivate(propertyDescriptor.getVisibility()))) {
|
||||||
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
|
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
|
||||||
}
|
}
|
||||||
else if (syntheticBackingField && context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration) {
|
else if (syntheticBackingField && context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration) {
|
||||||
|
|||||||
@@ -601,12 +601,13 @@ public abstract class MemberCodegen<T extends KtElement/* TODO: & JetDeclaration
|
|||||||
@Override
|
@Override
|
||||||
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
|
boolean syntheticBackingField = accessor instanceof AccessorForPropertyBackingFieldFromLocal;
|
||||||
boolean forceField = (JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
|
boolean forceFieldForCompanionProperty = JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
|
||||||
!isCompanionObject(accessor.getContainingDeclaration())) ||
|
!isCompanionObject(accessor.getContainingDeclaration());
|
||||||
|
boolean forceField = forceFieldForCompanionProperty ||
|
||||||
syntheticBackingField ||
|
syntheticBackingField ||
|
||||||
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
|
original.getVisibility() == JavaVisibilities.PROTECTED_STATIC_VISIBILITY;
|
||||||
StackValue property = codegen.intermediateValueForProperty(
|
StackValue property = codegen.intermediateValueForProperty(
|
||||||
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), true, StackValue.none()
|
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(), forceFieldForCompanionProperty, StackValue.none()
|
||||||
);
|
);
|
||||||
|
|
||||||
InstructionAdapter iv = codegen.v;
|
InstructionAdapter iv = codegen.v;
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class My {
|
||||||
|
companion object {
|
||||||
|
private val my: String = "O"
|
||||||
|
get() = field + "K"
|
||||||
|
|
||||||
|
fun getValue() = my
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = My.getValue()
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
class My {
|
||||||
|
companion object {
|
||||||
|
private val my: String = "O"
|
||||||
|
get() = { field }() + "K"
|
||||||
|
|
||||||
|
fun getValue() = my
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box() = My.getValue()
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
class IntentionsBundle {
|
||||||
|
companion object {
|
||||||
|
fun message(key: String): String {
|
||||||
|
return key + BUNDLE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun message2(key: String): String {
|
||||||
|
return { key + BUNDLE }()
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val BUNDLE = "K"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
if (IntentionsBundle.message("O") != "OK") return "fail 1: ${IntentionsBundle.message("O")}"
|
||||||
|
|
||||||
|
return IntentionsBundle.message2("O")
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import test.*
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return IntentionsBundle.message()
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
class IntentionsBundle {
|
||||||
|
companion object {
|
||||||
|
internal inline fun message(): String {
|
||||||
|
return KEY + BUNDLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val BUNDLE = "K"
|
||||||
|
protected const val KEY = "O"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
+18
@@ -6607,6 +6607,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("companionPrivateField.kt")
|
||||||
|
public void testCompanionPrivateField() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/companionPrivateField.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("companionPrivateFieldInsideLambda.kt")
|
||||||
|
public void testCompanionPrivateFieldInsideLambda() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/companionPrivateFieldInsideLambda.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("field.kt")
|
@TestMetadata("field.kt")
|
||||||
public void testField() throws Exception {
|
public void testField() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/field.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/field.kt");
|
||||||
@@ -6655,6 +6667,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt10729.kt")
|
||||||
|
public void testKt10729() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/kt10729.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt1159.kt")
|
@TestMetadata("kt1159.kt")
|
||||||
public void testKt1159() throws Exception {
|
public void testKt1159() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/kt1159.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/properties/kt1159.kt");
|
||||||
|
|||||||
+6
@@ -1308,6 +1308,12 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Private extends AbstractBlackBoxInlineCodegenTest {
|
public static class Private extends AbstractBlackBoxInlineCodegenTest {
|
||||||
|
@TestMetadata("accessorForConst.1.kt")
|
||||||
|
public void testAccessorForConst() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/accessorForConst.1.kt");
|
||||||
|
doTestMultiFileWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("accessorStability.1.kt")
|
@TestMetadata("accessorStability.1.kt")
|
||||||
public void testAccessorStability() throws Exception {
|
public void testAccessorStability() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/accessorStability.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/accessorStability.1.kt");
|
||||||
|
|||||||
+6
@@ -1308,6 +1308,12 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Private extends AbstractCompileKotlinAgainstInlineKotlinTest {
|
public static class Private extends AbstractCompileKotlinAgainstInlineKotlinTest {
|
||||||
|
@TestMetadata("accessorForConst.1.kt")
|
||||||
|
public void testAccessorForConst() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/accessorForConst.1.kt");
|
||||||
|
doBoxTestWithInlineCheck(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("accessorStability.1.kt")
|
@TestMetadata("accessorStability.1.kt")
|
||||||
public void testAccessorStability() throws Exception {
|
public void testAccessorStability() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/accessorStability.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/private/accessorStability.1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user