Do not check target when generating bridges with default impl

In many other places, e.g. org.jetbrains.kotlin.codegen.ClassBodyCodegen#generateDelegatesToDefaultImpl
we implicitly assume that whenever we use a default interface method
our target is 1.8

But here, we don't and it might lead to exception in org.jetbrains.kotlin.backend.common.bridges.BridgesKt#findConcreteSuperDeclaration
when actual target is 1.6 and we extend some AbstractMap implementation
with JDK8 (i.e., with @PlatformDependent getOrDefault)
This commit is contained in:
Denis Zharkov
2019-01-11 14:05:56 +03:00
parent 5ec93f2718
commit 2a156fe90c
2 changed files with 3 additions and 5 deletions
@@ -1064,7 +1064,7 @@ public class FunctionCodegen {
public void generateBridges(@NotNull FunctionDescriptor descriptor) { public void generateBridges(@NotNull FunctionDescriptor descriptor) {
if (descriptor instanceof ConstructorDescriptor) return; if (descriptor instanceof ConstructorDescriptor) return;
if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return; if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return;
if (JvmBridgesImplKt.isAbstractOnJvmIgnoringActualModality(state, descriptor)) return; if (JvmBridgesImplKt.isAbstractOnJvmIgnoringActualModality(descriptor)) return;
// equals(Any?), hashCode(), toString() never need bridges // equals(Any?), hashCode(), toString() never need bridges
if (isMethodOfAny(descriptor)) return; if (isMethodOfAny(descriptor)) return;
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.bridges.* import org.jetbrains.kotlin.backend.common.bridges.*
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -27,7 +26,7 @@ class DescriptorBasedFunctionHandleForJvm(
For non-@JvmDefault interfaces function, its body is generated in a separate place (DefaultImpls) and For non-@JvmDefault interfaces function, its body is generated in a separate place (DefaultImpls) and
the method in the interface is abstract so we must not generate bridges for such cases. the method in the interface is abstract so we must not generate bridges for such cases.
*/ */
override val isAbstract: Boolean = super.isAbstract || isAbstractOnJvmIgnoringActualModality(state, descriptor) override val isAbstract: Boolean = super.isAbstract || isAbstractOnJvmIgnoringActualModality(descriptor)
override val mayBeUsedAsSuperImplementation: Boolean = override val mayBeUsedAsSuperImplementation: Boolean =
super.mayBeUsedAsSuperImplementation || descriptor.isJvmDefaultOrPlatformDependent() super.mayBeUsedAsSuperImplementation || descriptor.isJvmDefaultOrPlatformDependent()
@@ -52,9 +51,8 @@ private fun needToGenerateDelegationToDefaultImpls(descriptor: FunctionDescripto
/** /**
* @return return true for interface method not annotated with @JvmDefault or @PlatformDependent * @return return true for interface method not annotated with @JvmDefault or @PlatformDependent
*/ */
fun isAbstractOnJvmIgnoringActualModality(state: GenerationState, descriptor: FunctionDescriptor): Boolean { fun isAbstractOnJvmIgnoringActualModality(descriptor: FunctionDescriptor): Boolean {
if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return false if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return false
if (state.target == JvmTarget.JVM_1_6) return true
return !descriptor.isJvmDefaultOrPlatformDependent() return !descriptor.isJvmDefaultOrPlatformDependent()
} }