diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 685eb5292e9..da0a51a5e7e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -254,7 +254,7 @@ public class FunctionCodegen { if(kind != OwnerKind.TRAIT_IMPL) { for (FunctionDescriptor overriddenFunction : overriddenFunctions) { // TODO should we check params here as well? - checkOverride(owner, state, v, jvmSignature, functionDescriptor, overriddenFunction); + checkOverride(owner, state, v, jvmSignature, functionDescriptor, overriddenFunction.getOriginal()); } checkOverride(owner, state, v, jvmSignature, functionDescriptor, functionDescriptor.getOriginal()); } @@ -412,26 +412,39 @@ public class FunctionCodegen { } } + private static boolean differentMethods(Method method, Method overriden) { + if(!method.getReturnType().equals(overriden.getReturnType())) + return true; + Type[] methodArgumentTypes = method.getArgumentTypes(); + Type[] overridenArgumentTypes = overriden.getArgumentTypes(); + if(methodArgumentTypes.length != overridenArgumentTypes.length) + return true; + for(int i = 0; i != methodArgumentTypes.length; ++i) + if(!methodArgumentTypes[i].equals(overridenArgumentTypes[i])) + return true; + return false; + } + private static void checkOverride(CodegenContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) { - Type type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType()); - Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType()); - if(!type1.equals(type2)) { - Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod(); + Method method = state.getTypeMapper().mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod(); + Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()).getAsmMethod(); + if(differentMethods(method, overriden)) { int flags = ACC_PUBLIC; // TODO. final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overriden.getDescriptor(), null, null); if (v.generateCode()) { mv.visitCode(); - Type[] argTypes = jvmSignature.getArgumentTypes(); + Type[] argTypes = overriden.getArgumentTypes(); InstructionAdapter iv = new InstructionAdapter(mv); iv.load(0, JetTypeMapper.TYPE_OBJECT); for (int i = 0, reg = 1; i < argTypes.length; i++) { Type argType = argTypes[i]; iv.load(reg, argType); if(argType.getSort() == Type.OBJECT) { - iv.checkcast(argType); + StackValue.onStack(JetTypeMapper.TYPE_OBJECT).put(method.getArgumentTypes()[i], iv); } + //noinspection AssignmentToForLoopParameter reg += argType.getSize(); } diff --git a/compiler/testData/codegen/regressions/kt940.kt b/compiler/testData/codegen/regressions/kt940.kt new file mode 100644 index 00000000000..8fb239af506 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt940.kt @@ -0,0 +1,15 @@ +import java.util.* + +fun box() : String { + val w = object : Comparator { + + override fun compare(o1 : String?, o2 : String?) : Int { + val l1 : Int = o1?.length ?: 0 + val l2 = o2?.length ?: 0 + return l1 - l2 + } + } + + w.compare("aaa", "bbb") + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 8ac25e8d012..e2a33a757cd 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -241,4 +241,8 @@ public class ClassGenTest extends CodegenTestCase { public void testKt903 () throws Exception { blackBoxFile("regressions/kt903.jet"); } + + public void testKt940 () throws Exception { + blackBoxFile("regressions/kt940.kt"); + } }