diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index 4b7bb93a8..ad29d3272 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -10186,9 +10186,9 @@ namespace PascalABCCompiler.NETGenerator il.Emit(OpCodes.Stsfld, vi.fb); il.Emit(OpCodes.Ldsfld, vi.fb); } - + } - + copy_string = false; } il.Emit(OpCodes.Stloc, pin_lb); @@ -10273,7 +10273,7 @@ namespace PascalABCCompiler.NETGenerator get_meth = mb.GetArrayMethod(ti.tp, "Get", CallingConventions.HasThis, elem_type, lst.ToArray()); addr_meth = mb.GetArrayMethod(ti.tp, "Address", CallingConventions.HasThis, elem_type.MakeByRefType(), lst.ToArray()); } - + for (int i = 0; i < indices.Length; i++) indices[i].visit(this); } @@ -10290,42 +10290,53 @@ namespace PascalABCCompiler.NETGenerator } else if (temp_is_dot_expr) + { + if (elem_type.IsGenericParameter) { - if (elem_type.IsGenericParameter) + if (value.array.type.element_type.is_generic_parameter && value.array.type.element_type.base_type != null && value.array.type.element_type.base_type.is_class && value.array.type.element_type.base_type.base_type != null) { - if (indices == null) - il.Emit(OpCodes.Ldelema, elem_type); - else - il.Emit(OpCodes.Call, addr_meth); - } - else if (elem_type.IsValueType == true) - { - if (indices == null) - il.Emit(OpCodes.Ldelema, elem_type); - else - il.Emit(OpCodes.Call, addr_meth); - } - else if (elem_type.IsPointer) - { - if (indices == null) - il.Emit(OpCodes.Ldelem_I); - else - il.Emit(OpCodes.Call, addr_meth); - } - else if (indices == null) il.Emit(OpCodes.Ldelem_Ref); else il.Emit(OpCodes.Call, get_meth); - + } + else + { + if (indices == null) + il.Emit(OpCodes.Ldelema, elem_type); + else + il.Emit(OpCodes.Call, addr_meth); + } + } - else + else if (elem_type.IsValueType == true) { if (indices == null) - NETGeneratorTools.PushLdelem(il, elem_type, true); + il.Emit(OpCodes.Ldelema, elem_type); else - il.Emit(OpCodes.Call, get_meth); + il.Emit(OpCodes.Call, addr_meth); } + else if (elem_type.IsPointer) + { + if (indices == null) + il.Emit(OpCodes.Ldelem_I); + else + il.Emit(OpCodes.Call, addr_meth); + } + else + if (indices == null) + il.Emit(OpCodes.Ldelem_Ref); + else + il.Emit(OpCodes.Call, get_meth); + + } + else + { + if (indices == null) + NETGeneratorTools.PushLdelem(il, elem_type, true); + else + il.Emit(OpCodes.Call, get_meth); + } is_addr = temp_is_addr; is_dot_expr = temp_is_dot_expr; //if (pinned_handle != null) diff --git a/TestSuite/generics75.pas b/TestSuite/generics75.pas new file mode 100644 index 000000000..c1b8e914e --- /dev/null +++ b/TestSuite/generics75.pas @@ -0,0 +1,26 @@ +var s: string; +type + c1 = class + where TSelf: c1; + x: string := 'abc'; + + static a := new TSelf[1]; + + static procedure p1; + begin + assert((a[0] as c1).x.Length = 3); // 3 + s := a[0].x; // nil + a[0].x := 'abc'; + assert((a[0] as c1).x.Length = 3); // 0 + end; + + end; + + c2 = class(c1) end; + +begin + c2.a[0] := new c2; + c2.p1; + assert(c2.a[0].x.Length = 3); // 0 + assert(s = 'abc'); +end. \ No newline at end of file