Fix for KT-9637: Runtime crash when using class literal in inline functions with reified type parameters
#KT-9637 Fixed
This commit is contained in:
@@ -2793,7 +2793,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
assert state.getReflectionTypes().getKClass().getTypeConstructor().equals(type.getConstructor())
|
||||
: "::class expression should be type checked to a KClass: " + type;
|
||||
|
||||
return generateClassLiteralReference(typeMapper, CollectionsKt.single(type.getArguments()).getType());
|
||||
return generateClassLiteralReference(typeMapper, CollectionsKt.single(type.getArguments()).getType(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2839,7 +2839,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static StackValue generateClassLiteralReference(@NotNull final JetTypeMapper typeMapper, @NotNull final KotlinType type) {
|
||||
public static StackValue generateClassLiteralReference(@NotNull JetTypeMapper typeMapper, @NotNull KotlinType type) {
|
||||
return generateClassLiteralReference(typeMapper, type, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static StackValue generateClassLiteralReference(@NotNull final JetTypeMapper typeMapper, @NotNull final KotlinType type, @Nullable final ExpressionCodegen codegen) {
|
||||
return StackValue.operation(K_CLASS_TYPE, new Function1<InstructionAdapter, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(InstructionAdapter v) {
|
||||
@@ -2849,11 +2854,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
|
||||
assert typeParameterDescriptor.isReified() :
|
||||
"Non-reified type parameter under ::class should be rejected by type checker: " + typeParameterDescriptor;
|
||||
v.visitLdcInsn(typeParameterDescriptor.getName().asString());
|
||||
v.invokestatic(
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME,
|
||||
Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)), false
|
||||
);
|
||||
assert codegen != null :
|
||||
"Reference to member of reified type should be rejected by type checker " + typeParameterDescriptor;
|
||||
codegen.putReifierMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.JAVA_CLASS_MARKER_METHOD_NAME);
|
||||
}
|
||||
|
||||
putJavaLangClassInstance(v, classAsmType);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//NO_CHECK_LAMBDA_INLINING
|
||||
import test.*
|
||||
|
||||
class Boxer {
|
||||
val box: () -> Box by injectFnc()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val box = Box()
|
||||
registerFnc { box }
|
||||
val prop = Boxer().box
|
||||
if (prop() != box) return "fail 1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package test
|
||||
|
||||
import java.util.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
val valuesInjectFnc = HashMap<KClass<out Any>, Any>()
|
||||
|
||||
inline fun <reified T : Any> injectFnc(): Lazy<Function0<T>> = lazy(LazyThreadSafetyMode.NONE) {
|
||||
(valuesInjectFnc[T::class] ?: throw Exception("no inject ${T::class.simpleName}")) as Function0<T>
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> registerFnc(noinline value: Function0<T>) {
|
||||
valuesInjectFnc[T::class] = value
|
||||
}
|
||||
|
||||
public class Box
|
||||
@@ -0,0 +1,8 @@
|
||||
import test.*
|
||||
|
||||
fun box(): String {
|
||||
val boxClass = injectFnc<Box>()
|
||||
if (boxClass != Box::class) return "fail 1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
inline fun <reified T : Any> injectFnc(): KClass<T> = {
|
||||
T::class
|
||||
} ()
|
||||
|
||||
public class Box
|
||||
|
||||
@@ -65,7 +65,6 @@ public object InlineTestUtil {
|
||||
val cr = ClassReader(bytes)
|
||||
|
||||
val inlineFunctions = inlineFunctionsJvmNames(bytes)
|
||||
if (inlineFunctions.isEmpty()) continue
|
||||
|
||||
val classVisitor = object : ClassVisitorWithName() {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor {
|
||||
|
||||
+12
@@ -1108,6 +1108,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9637.1.kt")
|
||||
public void testKt9637() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/reified/kt9637.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9637_2.1.kt")
|
||||
public void testKt9637_2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/reified/kt9637_2.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("packages.1.kt")
|
||||
public void testPackages() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/reified/packages.1.kt");
|
||||
|
||||
+12
@@ -1108,6 +1108,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9637.1.kt")
|
||||
public void testKt9637() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/reified/kt9637.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9637_2.1.kt")
|
||||
public void testKt9637_2() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/reified/kt9637_2.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("packages.1.kt")
|
||||
public void testPackages() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/reified/packages.1.kt");
|
||||
|
||||
Reference in New Issue
Block a user