Skip to content

Commit

Permalink
Setting value of enums didn't properly widen the value when setting (#…
Browse files Browse the repository at this point in the history
…43779)

Use VerifierCorElementType instead of SignatureCorElementType to specify the element type of the target field
- This will send the runtime down the path which can perform primitive widening
  • Loading branch information
davidwrighton authored Oct 26, 2020
1 parent b0be1ab commit c08ac77
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/src/vm/reflectioninvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ FCIMPL7(void, RuntimeFieldHandle::SetValue, ReflectFieldObject *pFieldUNSAFE, Ob

HELPER_METHOD_FRAME_BEGIN_PROTECT(gc);

InvokeUtil::SetValidField(fieldType.GetSignatureCorElementType(), fieldType, pFieldDesc, &gc.target, &gc.value, declaringType, pDomainInitialized);
InvokeUtil::SetValidField(fieldType.GetVerifierCorElementType(), fieldType, pFieldDesc, &gc.target, &gc.value, declaringType, pDomainInitialized);

HELPER_METHOD_FRAME_END();
}
Expand Down
24 changes: 17 additions & 7 deletions src/libraries/System.Reflection/tests/FieldInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,23 +86,26 @@ public void GetValue_Invalid(Type type, string name, object obj, Type exceptionT

public static IEnumerable<object[]> SetValue_TestData()
{
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.s_intField), new FieldInfoTests(), 1000 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.s_intField), null, 1000 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.intField), new FieldInfoTests(), 1000 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.s_stringField), new FieldInfoTests(), "new" };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.stringField), new FieldInfoTests(), "new" };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.s_intField), new FieldInfoTests(), 1000, 1000 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.s_intField), null, 1000, 1000 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.intField), new FieldInfoTests(), 1000, 1000 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.s_stringField), new FieldInfoTests(), "new", "new" };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.stringField), new FieldInfoTests(), "new", "new" };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.shortEnumField), new FieldInfoTests(), (byte)1, (ShortEnum)1 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.intEnumField), new FieldInfoTests(), (short)2, (IntEnum)2 };
yield return new object[] { typeof(FieldInfoTests), nameof(FieldInfoTests.longEnumField), new FieldInfoTests(), (int)3, (LongEnum)3 };
}

[Theory]
[MemberData(nameof(SetValue_TestData))]
public void SetValue(Type type, string name, object obj, object value)
public void SetValue(Type type, string name, object obj, object value, object expected)
{
FieldInfo fieldInfo = GetField(type, name);
object original = fieldInfo.GetValue(obj);
try
{
fieldInfo.SetValue(obj, value);
Assert.Equal(value, fieldInfo.GetValue(obj));
Assert.Equal(expected, fieldInfo.GetValue(obj));
}
finally
{
Expand Down Expand Up @@ -453,6 +456,13 @@ private static FieldInfo GetField(Type type, string name)
public int intField = 101;
public string stringField = "non static";

public enum ShortEnum : short {}
public enum IntEnum {}
public enum LongEnum : long {}
public ShortEnum shortEnumField;
public IntEnum intEnumField;
public LongEnum longEnumField;

private int privateIntField = 1;
private string privateStringField = "privateStringField";

Expand Down
10 changes: 10 additions & 0 deletions src/libraries/System.Reflection/tests/PropertyInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public static IEnumerable<object[]> SetValue_TestData()
yield return new object[] { typeof(BaseClass), nameof(BaseClass.Name), new BaseClass(), "hello", null, "hello" };
yield return new object[] { typeof(AdvancedIndexerClass), "Item", new AdvancedIndexerClass(), "hello", new object[] { 99, 2, new string[] { "hello" }, "f" }, "992f1" };
yield return new object[] { typeof(AdvancedIndexerClass), "Item", new AdvancedIndexerClass(), "pw", new object[] { 99, 2, new string[] { "hello" }, "SOME string" }, "992SOME string1" };
yield return new object[] { typeof(BaseClass), nameof(BaseClass.ShortEnumProperty), new BaseClass(), (byte)1, null, (BaseClass.ShortEnum)1 };
yield return new object[] { typeof(BaseClass), nameof(BaseClass.IntEnumProperty), new BaseClass(), (short)2, null, (BaseClass.IntEnum)2 };
yield return new object[] { typeof(BaseClass), nameof(BaseClass.LongEnumProperty), new BaseClass(), (int)3, null, (BaseClass.LongEnum)3 };
}

[Theory]
Expand Down Expand Up @@ -358,6 +361,13 @@ public static object[] StaticObjectArrayProperty
set { _staticObjectArrayProperty = value; }
}

public enum ShortEnum : short {}
public enum IntEnum {}
public enum LongEnum : long {}
public ShortEnum ShortEnumProperty { get; set; }
public IntEnum IntEnumProperty { get; set; }
public LongEnum LongEnumProperty { get; set; }

public object[] _objectArray;
public object[] ObjectArrayProperty
{
Expand Down

0 comments on commit c08ac77

Please sign in to comment.