Setting value of enums didn't properly widen the value when setting (#43779)
authorDavid Wrighton <davidwr@microsoft.com>
Mon, 26 Oct 2020 18:41:25 +0000 (11:41 -0700)
committerGitHub <noreply@github.com>
Mon, 26 Oct 2020 18:41:25 +0000 (11:41 -0700)
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

src/coreclr/src/vm/reflectioninvocation.cpp
src/libraries/System.Reflection/tests/FieldInfoTests.cs
src/libraries/System.Reflection/tests/PropertyInfoTests.cs

index 19f70d5..0051a93 100644 (file)
@@ -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();
 }
index 1a513a2..c06becb 100644 (file)
@@ -86,23 +86,26 @@ namespace System.Reflection.Tests
 
         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
             {
@@ -453,6 +456,13 @@ namespace System.Reflection.Tests
         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";
 
index 426fbca..bc47740 100644 (file)
@@ -96,6 +96,9 @@ namespace System.Reflection.Tests
             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]
@@ -358,6 +361,13 @@ namespace System.Reflection.Tests
                 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
             {