diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index b6c4b4c50..bfe1aa479 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -7550,11 +7550,11 @@ namespace PascalABCCompiler.NETGenerator private void BoxAssignToParameter(IExpressionNode to, IExpressionNode from) { ICompiledTypeNode ctn2 = to.type as ICompiledTypeNode; - if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) + if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && (ctn2.compiled_type == TypeFactory.ObjectType || ctn2.IsInterface)) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.type).tp); } - else if (from.conversion_type != null && (from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) + else if (from.conversion_type != null && (from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && (ctn2.compiled_type == TypeFactory.ObjectType || ctn2.IsInterface)) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.conversion_type).tp); } @@ -7940,11 +7940,15 @@ namespace PascalABCCompiler.NETGenerator return; } ICompiledTypeNode ctn2 = to.type as ICompiledTypeNode; - if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) + if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && (ctn2.compiled_type == TypeFactory.ObjectType || ctn2.IsInterface)) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.type).tp); } - else if (from.conversion_type != null && (from.conversion_type.is_value_type || from.conversion_type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) + else if ((from.type.is_value_type || from.type.is_generic_parameter) && to.type.IsInterface) + { + il.Emit(OpCodes.Box, helper.GetTypeReference(from.type).tp); + } + else if (from.conversion_type != null && (from.conversion_type.is_value_type || from.conversion_type.is_generic_parameter) && ctn2 != null && (ctn2.compiled_type == TypeFactory.ObjectType || ctn2.IsInterface)) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.conversion_type).tp); } @@ -7977,11 +7981,11 @@ namespace PascalABCCompiler.NETGenerator } //ICompiledTypeNode ctn = from.type as ICompiledTypeNode; ICompiledTypeNode ctn2 = to.type as ICompiledTypeNode; - if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) + if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && (ctn2.compiled_type == TypeFactory.ObjectType || (ctn2.compiled_type == TypeFactory.ObjectType || ctn2.compiled_type.IsInterface))) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.type).tp); } - else if (from.conversion_type != null && (from.conversion_type.is_value_type || from.conversion_type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) + else if (from.conversion_type != null && (from.conversion_type.is_value_type || from.conversion_type.is_generic_parameter) && ctn2 != null && (ctn2.compiled_type == TypeFactory.ObjectType || ctn2.compiled_type.IsInterface)) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.conversion_type).tp); } diff --git a/TestSuite/boxing2.pas b/TestSuite/boxing2.pas new file mode 100644 index 000000000..95fc9291b --- /dev/null +++ b/TestSuite/boxing2.pas @@ -0,0 +1,22 @@ +type + Ir1=interface end; + + r1=record(Ir1) + i: integer; + end; + +procedure Test(i: Ir1); +begin + assert(r1(i).i = 2); +end; + +begin + var a := new Ir1[1]; + var rrr: r1; + rrr.i := 2; + a[0] := rrr; + var i1: Ir1 := rrr; + assert(r1(a[0]).i = 2); + assert(r1(i1).i = 2); + Test(a[0]); +end. \ No newline at end of file