Open
0 of 1 issue completedDescription
class Foo<T>
{
public T item;
public void SetItem(T v) => item = v;
}
generates the following snippet for the SetItem()
method:
//Method : SetItem
var md_SetItem_3 = new MethodDefinition("SetItem", MethodAttributes.Public | MethodAttributes.HideBySig, assembly.MainModule.TypeSystem.Void);
cls_Foo_0.Methods.Add(md_SetItem_3);
md_SetItem_3.Body.InitLocals = true;
var il_SetItem_4 = md_SetItem_3.Body.GetILProcessor();
//Parameters of 'public void SetItem(T v) => item = v;'
var p_v_5 = new ParameterDefinition("v", ParameterAttributes.None, gp_T_1);
md_SetItem_3.Parameters.Add(p_v_5);
//item = v
il_SetItem_4.Emit(OpCodes.Ldarg_0);
il_SetItem_4.Emit(OpCodes.Ldarg_1);
il_SetItem_4.Emit(OpCodes.Stfld, fld_Item_2);
il_SetItem_4.Emit(OpCodes.Ret);
the line
il_SetItem_4.Emit(OpCodes.Stfld, fld_Item_2);
produces the following IL:
IL_0002: stfld !0 Foo`1::item
which is incorrect.
The IL generated by the C# compiler is:
IL_0002: stfld !0 Foo`1<!T>::item
This seems to happen because the parent of fld_Item_2
is a generic type definition when it should be a generic instance type.
if we replace the line that set the field with something like:
var newParent = new GenericInstanceType(cls_Foo_0);
newParent.GenericArguments.Add(gp_T_1);
var newFieldReference = new FieldReference("item", gp_T_1);
newFieldReference.DeclaringType = newParent;
il_SetItem_4.Emit(OpCodes.Stfld, newFieldReference);
then the generated IL matches the one generated by the C# compiler.
Note
Interestingly enough both ilverify
and the runtime are happy with the "invalid" IL. Maybe with more complex types (or type hierarchies) it may result runtime errors?
We should also check other member types:
- Properties
- Events
- Methods