Fix for KT-14966: Regression: VerifyError on access super implementation from delegate
#KT-14966 Fixed
This commit is contained in:
@@ -2595,7 +2595,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context, state.getShouldInlineConstVals())) {
|
||||
propertyDescriptor = context.getAccessorForSuperCallIfNeeded(propertyDescriptor, superCallTarget);
|
||||
propertyDescriptor = context.getAccessorForSuperCallIfNeeded(propertyDescriptor, superCallTarget, state);
|
||||
|
||||
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
|
||||
|
||||
@@ -2765,7 +2765,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor fd = accessibleFunctionDescriptor(resolvedCall);
|
||||
ClassDescriptor superCallTarget = getSuperCallTarget(call);
|
||||
|
||||
fd = context.getAccessorForSuperCallIfNeeded(fd, superCallTarget);
|
||||
fd = context.getAccessorForSuperCallIfNeeded(fd, superCallTarget, state);
|
||||
|
||||
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
|
||||
if (!codegenExtensions.isEmpty()) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.*;
|
||||
import org.jetbrains.kotlin.psi.Call;
|
||||
@@ -98,6 +99,17 @@ public class JvmCodegenUtil {
|
||||
return isJvm8InterfaceWithDefaults(declaration, state);
|
||||
}
|
||||
|
||||
public static boolean isNonDefaultInterfaceMember(@NotNull CallableMemberDescriptor descriptor, @NotNull GenerationState state) {
|
||||
if (!isJvmInterface(descriptor.getContainingDeclaration())) {
|
||||
return false;
|
||||
}
|
||||
if (descriptor instanceof JavaCallableMemberDescriptor) {
|
||||
return descriptor.getModality() == Modality.ABSTRACT;
|
||||
}
|
||||
|
||||
return !isJvm8InterfaceWithDefaultsMember(descriptor, state);
|
||||
}
|
||||
|
||||
public static boolean isJvmInterface(DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
ClassKind kind = ((ClassDescriptor) descriptor).getKind();
|
||||
|
||||
@@ -67,6 +67,7 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
||||
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
@@ -771,7 +772,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
|
||||
);
|
||||
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) && !isInterface(functionDescriptor.getContainingDeclaration());
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) && !isNonDefaultInterfaceMember(functionDescriptor, state);
|
||||
int reg = hasDispatchReceiver ? 1 : 0;
|
||||
boolean accessorIsConstructor = accessorDescriptor instanceof AccessorForConstructorDescriptor;
|
||||
if (!accessorIsConstructor && functionDescriptor instanceof ConstructorDescriptor) {
|
||||
|
||||
@@ -37,7 +37,7 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUtilKt.isInlineOnlyOrReifiable;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
@@ -391,8 +391,11 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@NotNull
|
||||
public <D extends CallableMemberDescriptor> D getAccessorForSuperCallIfNeeded(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
|
||||
if (superCallTarget != null && !isJvmInterface(descriptor.getContainingDeclaration())) {
|
||||
public <D extends CallableMemberDescriptor> D getAccessorForSuperCallIfNeeded(
|
||||
@NotNull D descriptor,
|
||||
@Nullable ClassDescriptor superCallTarget,
|
||||
@NotNull GenerationState state) {
|
||||
if (superCallTarget != null && !isNonDefaultInterfaceMember(descriptor, state)) {
|
||||
CodegenContext afterInline = getFirstCrossInlineOrNonInlineContext();
|
||||
CodegenContext c = afterInline.findParentContextWithDescriptor(superCallTarget);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + descriptor;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// FILE: IBase.java
|
||||
|
||||
interface IBase {
|
||||
default String bar() {
|
||||
return "OK";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Kotlin.kt
|
||||
open class Base {
|
||||
fun foo() = "OK"
|
||||
}
|
||||
|
||||
class C : Base(), IBase {
|
||||
val lambda1 = {
|
||||
super.foo()
|
||||
}
|
||||
|
||||
val lambda2 = {
|
||||
super.bar()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (C().lambda1() != "OK") return "fail 1"
|
||||
|
||||
return C().lambda2()
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// JVM_TARGET: 1.8
|
||||
// FILE: IBase.java
|
||||
|
||||
interface IBase {
|
||||
default String bar() {
|
||||
return "OK";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Kotlin.kt
|
||||
open class Base {
|
||||
fun foo() = "OK"
|
||||
}
|
||||
|
||||
class C : Base(), IBase {
|
||||
val lambda1 = {
|
||||
super.foo()
|
||||
}
|
||||
|
||||
val lambda2 = {
|
||||
super.bar()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (C().lambda1() != "OK") return "fail 1"
|
||||
|
||||
return C().lambda2()
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// JVM_TARGET: 1.8
|
||||
// KOTLIN_CONFIGURATION_FLAGS: +JVM.JVM8_TARGET_WITH_DEFAULTS
|
||||
|
||||
interface IBase {
|
||||
fun bar() = "OK"
|
||||
}
|
||||
|
||||
open class Base {
|
||||
fun foo() = "OK"
|
||||
}
|
||||
|
||||
class C : Base(), IBase {
|
||||
val lambda1 = {
|
||||
super.foo()
|
||||
}
|
||||
|
||||
val lambda2 = {
|
||||
super.bar()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (C().lambda1() != "OK") return "fail 1"
|
||||
|
||||
return C().lambda2()
|
||||
}
|
||||
+18
@@ -48,6 +48,12 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("capturedSuperCall.kt")
|
||||
public void testCapturedSuperCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/capturedSuperCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultMethodCallFromInterface.kt")
|
||||
public void testDefaultMethodCallFromInterface() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/defaultMethodCallFromInterface.kt");
|
||||
@@ -197,6 +203,12 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("capturedSuperCall.kt")
|
||||
public void testCapturedSuperCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/capturedSuperCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgs.kt")
|
||||
public void testDefaultArgs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/defaultArgs.kt");
|
||||
@@ -283,6 +295,12 @@ public class BlackBoxWithJava8CodegenTestGenerated extends AbstractBlackBoxCodeg
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("capturedSuperCall.kt")
|
||||
public void testCapturedSuperCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/defaults/capturedSuperCall.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgs.kt")
|
||||
public void testDefaultArgs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/java8/box/jvm8/defaults/defaultArgs.kt");
|
||||
|
||||
Reference in New Issue
Block a user