From 51e4fc986af560442de500cd3f985a2c4e0e383e Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Fri, 27 Jan 2012 15:40:17 +0300 Subject: [PATCH] KT-1157 class object instance access from constructor of class object --- .../jetbrains/jet/codegen/ClosureCodegen.java | 2 +- .../jetbrains/jet/codegen/CodegenUtil.java | 7 ++ .../jet/codegen/ExpressionCodegen.java | 15 +++- .../codegen/ImplementationBodyCodegen.java | 78 +++++++++---------- .../jetbrains/jet/codegen/JetTypeMapper.java | 1 + .../testData/codegen/regressions/kt1157.kt | 28 +++++++ .../jetbrains/jet/codegen/ClassGenTest.java | 4 + 7 files changed, 90 insertions(+), 45 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt1157.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index ac955d16cac..75a7a56eaeb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -145,7 +145,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { private void generateConstInstance(PsiElement fun) { String classDescr = "L" + name + ";"; - cv.newField(fun, ACC_PRIVATE | ACC_STATIC, "$instance", classDescr, null, null); + cv.newField(fun, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "$instance", classDescr, null, null); MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_STATIC, "$getInstance", "()" + classDescr, null, new String[0]); if (cv.generateCode()) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 176502c3e82..c500e640bc1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -3,6 +3,9 @@ package org.jetbrains.jet.codegen; import gnu.trove.THashSet; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.psi.JetClassObject; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.resolve.calls.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; @@ -126,4 +129,8 @@ public class CodegenUtil { } } + static boolean isNonLiteralObject(JetClassOrObject myClass) { + return myClass instanceof JetObjectDeclaration && !((JetObjectDeclaration) myClass).isObjectLiteral() && + !(myClass.getParent() instanceof JetClassObject); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 4fc5100efc7..c552c78b40d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1375,6 +1375,10 @@ public class ExpressionCodegen extends JetVisitor { public StackValue generateThisOrOuter(ClassDescriptor calleeContainingClass) { CodegenContext cur = context; + PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, calleeContainingClass); + boolean isObject = psiElement instanceof JetClassOrObject && CodegenUtil.isNonLiteralObject((JetClassOrObject)psiElement); + + cur = context; StackValue result = StackValue.local(0, TYPE_OBJECT); while (cur != null) { if(cur instanceof CodegenContext.MethodContext && !(cur instanceof CodegenContext.ConstructorContext)) @@ -1382,8 +1386,13 @@ public class ExpressionCodegen extends JetVisitor { if (CodegenUtil.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) { Type type = asmType(calleeContainingClass.getDefaultType()); - result.put(TYPE_OBJECT, v); - return castToRequiredTypeOfInterfaceIfNeeded(StackValue.onStack(type), cur.getThisDescriptor(), calleeContainingClass); + if(!isObject || (cur.getThisDescriptor() == calleeContainingClass)) { + result.put(TYPE_OBJECT, v); + return castToRequiredTypeOfInterfaceIfNeeded(StackValue.onStack(type), cur.getThisDescriptor(), calleeContainingClass); + } + else { + v.getstatic(type.getInternalName(), "$instance", type.getDescriptor()); + } } result = cur.getOuterExpression(result); @@ -2345,7 +2354,7 @@ public class ExpressionCodegen extends JetVisitor { @Override public StackValue visitThrowExpression(JetThrowExpression expression, StackValue receiver) { - gen(expression.getThrownExpression(), TYPE_OBJECT); + gen(expression.getThrownExpression(), TYPE_THROWABLE); doFinallyOnReturnOrThrow(); v.athrow(); return StackValue.none(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 3ed944f727f..87b337ef923 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -22,6 +22,7 @@ import org.objectweb.asm.commons.Method; import java.util.*; import static org.jetbrains.jet.codegen.JetTypeMapper.TYPE_OBJECT; +import static org.objectweb.asm.Opcodes.*; /** * @author max @@ -70,20 +71,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } int access = 0; - access |= Opcodes.ACC_PUBLIC; + access |= ACC_PUBLIC; if (isAbstract) { - access |= Opcodes.ACC_ABSTRACT; + access |= ACC_ABSTRACT; } if (isInterface) { - access |= Opcodes.ACC_INTERFACE; // ACC_SUPER + access |= ACC_INTERFACE; // ACC_SUPER } if (isFinal) { - access |= Opcodes.ACC_FINAL; + access |= ACC_FINAL; } if (isStatic) { - access |= Opcodes.ACC_STATIC; + access |= ACC_STATIC; } - v.defineClass(myClass, Opcodes.V1_6, + v.defineClass(myClass, V1_6, access, signature.getName(), signature.getJavaGenericSignature(), @@ -99,11 +100,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (ClassDescriptor innerClass : descriptor.getInnerClassesAndObjects()) { // TODO: proper access - int innerClassAccess = Opcodes.ACC_PUBLIC; + int innerClassAccess = ACC_PUBLIC; if (innerClass.getModality() == Modality.FINAL) { - innerClassAccess |= Opcodes.ACC_FINAL; + innerClassAccess |= ACC_FINAL; } else if (innerClass.getModality() == Modality.ABSTRACT) { - innerClassAccess |= Opcodes.ACC_ABSTRACT; + innerClassAccess |= ACC_ABSTRACT; } // TODO: cache internal names String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); @@ -242,7 +243,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method originalMethod = typeMapper.mapSignature(original.getName(), original).getAsmMethod(); Type[] argTypes = method.getArgumentTypes(); - MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null); + MethodVisitor mv = v.newMethod(null, ACC_PUBLIC| ACC_BRIDGE| ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null); if (v.generateCode()) { mv.visitCode(); @@ -269,7 +270,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); + MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter()); if (v.generateCode()) { mv.visitCode(); @@ -292,7 +293,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); + MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter()); if (v.generateCode()) { mv.visitCode(); @@ -323,9 +324,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateFieldForObjectInstance() { - if (isNonLiteralObject()) { + if (CodegenUtil.isNonLiteralObject(myClass)) { Type type = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION); - v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$instance", type.getDescriptor(), null, null); + v.newField(myClass, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, "$instance", type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @Override @@ -346,7 +347,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (classObject != null) { final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName()); - v.newField(classObject, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$classobj", type.getDescriptor(), null, null); + v.newField(classObject, ACC_PUBLIC | ACC_STATIC, "$classobj", type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @Override @@ -398,7 +399,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { signatureWriter.writeVoidReturn(); constructorMethod = signatureWriter.makeJvmMethodSignature(""); - callableMethod = new CallableMethod("", constructorMethod, Opcodes.INVOKESPECIAL); + callableMethod = new CallableMethod("", constructorMethod, INVOKESPECIAL); } else { callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind); @@ -450,7 +451,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { constructorMethod = JvmMethodSignature.simple("", Type.VOID_TYPE, consArgTypes); } - int flags = Opcodes.ACC_PUBLIC; // TODO + int flags = ACC_PUBLIC; // TODO final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null); if (!v.generateCode()) return; @@ -553,7 +554,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { String delegateField = "$delegate_" + n; Type fieldType = typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION); String fieldDesc = fieldType.getDescriptor(); - v.newField(specifier, Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); + v.newField(specifier, ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); iv.putfield(classname, delegateField, fieldDesc); JetClass superClass = (JetClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); @@ -569,17 +570,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final Type type = typeMapper.mapType(outerDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION); String interfaceDesc = type.getDescriptor(); final String fieldName = "this$0"; - v.newField(myClass, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null); + v.newField(myClass, ACC_PRIVATE | ACC_FINAL, fieldName, interfaceDesc, null, null); iv.load(0, classType); iv.load(frameMap.getOuterThisIndex(), type); iv.putfield(classname, fieldName, interfaceDesc); Type outerType = typeMapper.mapType(outerDescriptor.getDefaultType()); - MethodVisitor outer = v.newMethod(myClass, Opcodes.ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, "()Ljet/JetObject;", null, null); + MethodVisitor outer = v.newMethod(myClass, ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, "()Ljet/JetObject;", null, null); outer.visitCode(); - outer.visitVarInsn(Opcodes.ALOAD, 0); - outer.visitFieldInsn(Opcodes.GETFIELD, classname, "this$0", outerType.getDescriptor()); - outer.visitInsn(Opcodes.ARETURN); + outer.visitVarInsn(ALOAD, 0); + outer.visitFieldInsn(GETFIELD, classname, "this$0", outerType.getDescriptor()); + outer.visitInsn(ARETURN); FunctionCodegen.endVisit(outer, JvmStdlibNames.JET_OBJECT_GET_OUTER_OBJECT_METHOD, myClass); } @@ -631,7 +632,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { generateTraitMethods(codegen); - mv.visitInsn(Opcodes.RETURN); + mv.visitInsn(RETURN); FunctionCodegen.endVisit(mv, "constructor", myClass); FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, OwnerKind.IMPLEMENTATION); @@ -651,7 +652,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if(psiElement instanceof JetClass) { JetClass jetClass = (JetClass) psiElement; if(jetClass.isTrait()) { - int flags = Opcodes.ACC_PUBLIC; // TODO. + int flags = ACC_PUBLIC; // TODO. Method function = typeMapper.mapSignature(fun.getName(), fun).getAsmMethod(); Method functionOriginal = typeMapper.mapSignature(fun.getName(), fun.getOriginal()).getAsmMethod(); @@ -745,7 +746,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) { String name = declaration.getName(); final String desc = "L" + typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName() + ";"; - v.newField(declaration, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, name, desc, null, null); + v.newField(declaration, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, name, desc, null, null); if (myEnumConstants.isEmpty()) { staticInitializerChunks.add(new CodeChunk() { @Override @@ -802,7 +803,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { throw new UnsupportedOperationException("failed to get descriptor for secondary constructor"); } CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind); - int flags = Opcodes.ACC_PUBLIC; // TODO + int flags = ACC_PUBLIC; // TODO final MethodVisitor mv = v.newMethod(constructor, flags, "", method.getSignature().getAsmMethod().getDescriptor(), null, null); if (v.generateCode()) { mv.visitCode(); @@ -831,7 +832,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { codegen.gen(bodyExpression, Type.VOID_TYPE); } - mv.visitInsn(Opcodes.RETURN); + mv.visitInsn(RETURN); FunctionCodegen.endVisit(mv, "constructor", null); } } @@ -908,9 +909,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (p.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p); if (propertyDescriptor != null) { - propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); + propertyCodegen.generateDefaultGetter(propertyDescriptor, ACC_PUBLIC, p); if (propertyDescriptor.isVar()) { - propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); + propertyCodegen.generateDefaultSetter(propertyDescriptor, ACC_PUBLIC, p); } } } @@ -922,11 +923,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return myClass instanceof JetClass ? ((JetClass) myClass).getClassObject() : null; } - private boolean isNonLiteralObject() { - return myClass instanceof JetObjectDeclaration && !((JetObjectDeclaration) myClass).isObjectLiteral() && - !(myClass.getParent() instanceof JetClassObject); - } - private void generateGetTypeInfo() { if(myClass instanceof JetClass && ((JetClass)myClass).isTrait()) return; @@ -934,9 +930,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetType defaultType = descriptor.getDefaultType(); if(CodegenUtil.requireTypeInfoConstructorArg(defaultType)) { if(!CodegenUtil.hasDerivedTypeInfoField(defaultType)) { - v.newField(myClass, Opcodes.ACC_PROTECTED, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;", null, null); + v.newField(myClass, ACC_PROTECTED, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;", null, null); - MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;", null, null); + MethodVisitor mv = v.newMethod(myClass, ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;", null, null); if (v.generateCode()) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); @@ -947,7 +943,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { FunctionCodegen.endVisit(iv, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, myClass); } - mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, JvmAbi.SET_TYPE_INFO_METHOD, "(Ljet/TypeInfo;)V", null, null); + mv = v.newMethod(myClass, ACC_PROTECTED | ACC_FINAL, JvmAbi.SET_TYPE_INFO_METHOD, "(Ljet/TypeInfo;)V", null, null); if (v.generateCode()) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); @@ -955,7 +951,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(1, JetTypeMapper.TYPE_OBJECT); iv.putfield(owner, JvmAbi.TYPE_INFO_FIELD, "Ljet/TypeInfo;"); - mv.visitInsn(Opcodes.RETURN); + mv.visitInsn(RETURN); FunctionCodegen.endVisit(iv, JvmAbi.SET_TYPE_INFO_METHOD, myClass); } } @@ -967,7 +963,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void genGetStaticGetTypeInfoMethod() { - final MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;", null, null); + final MethodVisitor mv = v.newMethod(myClass, ACC_PUBLIC, JvmStdlibNames.JET_OBJECT_GET_TYPEINFO_METHOD, "()Ljet/TypeInfo;", null, null); if (v.generateCode()) { mv.visitCode(); InstructionAdapter v = new InstructionAdapter(mv); @@ -979,7 +975,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void staticTypeInfoField() { - v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$staticTypeInfo", "Ljet/TypeInfo;", null, null); + v.newField(myClass, ACC_PUBLIC | ACC_FINAL | ACC_STATIC, "$staticTypeInfo", "Ljet/TypeInfo;", null, null); staticInitializerChunks.add(new CodeChunk() { @Override public void generate(InstructionAdapter v) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 1d8e52d7eee..a9174fb44a3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -31,6 +31,7 @@ import static org.objectweb.asm.Opcodes.*; */ public class JetTypeMapper { public static final Type TYPE_OBJECT = Type.getObjectType("java/lang/Object"); + public static final Type TYPE_THROWABLE = Type.getObjectType("java/lang/Throwable"); public static final Type TYPE_TYPEINFO = Type.getType(TypeInfo.class); public static final Type TYPE_TYPEINFOPROJECTION = Type.getType(TypeInfoProjection.class); public static final Type TYPE_JET_OBJECT = Type.getType(JetObject.class); diff --git a/compiler/testData/codegen/regressions/kt1157.kt b/compiler/testData/codegen/regressions/kt1157.kt new file mode 100644 index 00000000000..31d6f075c8a --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1157.kt @@ -0,0 +1,28 @@ +public object SomeClass { + var bug: Any = "" + + private val workerThread = object : Thread() { + override fun run() { + try { + foo() + bug = "none" + } + catch(t: Throwable) { + bug = t + } + } + } + + { + workerThread.start() + } + + private fun foo() : Unit { + } +} + +public fun box():String { + if(SomeClass.bug is Throwable) + throw SomeClass.bug + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java index e24255938c0..5440347b3eb 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -257,4 +257,8 @@ public class ClassGenTest extends CodegenTestCase { public void testkt1134() throws Exception { blackBoxFile("regressions/kt1134.kt"); } + + public void testkt1157() throws Exception { + blackBoxFile("regressions/kt1157.kt"); + } }