Ensure re-used local is initialized (#40694)
authorCharles Stoner <chucks@microsoft.com>
Wed, 12 Aug 2020 15:24:45 +0000 (08:24 -0700)
committerGitHub <noreply@github.com>
Wed, 12 Aug 2020 15:24:45 +0000 (15:24 +0000)
src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Expressions.cs
src/libraries/System.Linq.Expressions/tests/Cast/CastTests.cs

index eab9438..f29424e 100644 (file)
@@ -1123,6 +1123,8 @@ namespace System.Linq.Expressions.Compiler
                         Label exit = _ilg.DefineLabel();
                         Label exitNull = _ilg.DefineLabel();
                         LocalBuilder anyNull = GetLocal(typeof(bool));
+                        _ilg.Emit(OpCodes.Ldc_I4_0);
+                        _ilg.Emit(OpCodes.Stloc, anyNull);
                         for (int i = 0, n = paramList.Length; i < n; i++)
                         {
                             ParameterExpression v = paramList[i];
index 216c26e..090878f 100644 (file)
@@ -2378,19 +2378,19 @@ namespace System.Linq.Expressions.Tests
 #endif
         }
 
-        public static IEnumerable<object[]> EnumerableTypeArgs() => EnumerableTypes().Select(t => new object[] {t});
+        public static IEnumerable<object[]> EnumerableTypeArgs() => EnumerableTypes().Select(t => new object[] { t });
 
         public static IEnumerable<object[]> EnumerableTypesAndIncompatibleObjects()
             => from value in EnumerableTypes().Select(Activator.CreateInstance)
-                from type in EnumerableTypes()
-                where type != value.GetType()
-                select new[] {type, value};
+               from type in EnumerableTypes()
+               where type != value.GetType()
+               select new[] { type, value };
 
         public static IEnumerable<object[]> EnumerableTypesAndIncompatibleUnderlyingObjects()
             => from value in EnumerableTypes().Select(t => Activator.CreateInstance(Enum.GetUnderlyingType(t)))
-                from type in EnumerableTypes()
-                where Enum.GetUnderlyingType(type) != value.GetType()
-                select new[] {type, value};
+               from type in EnumerableTypes()
+               where Enum.GetUnderlyingType(type) != value.GetType()
+               select new[] { type, value };
 
         [Theory, PerCompilationType(nameof(EnumerableTypeArgs))]
         public static void CanCastReferenceToUnderlyingTypeToEnumType(Type type, bool useInterpreter)
@@ -2511,5 +2511,43 @@ namespace System.Linq.Expressions.Tests
             Action act = exp.Compile(useInterpreter);
             Assert.Throws<InvalidCastException>(act);
         }
+
+        public static IEnumerable<object[]> GreaterThanOrEqualToOneArguments => new[]
+        {
+            new object[] { typeof(decimal?), 1m },
+            new object[] { typeof(decimal), 1m },
+            new object[] { typeof(int?), 1 },
+            new object[] { typeof(int), 1 },
+            new object[] { typeof(long?), 1L },
+            new object[] { typeof(long), 1L },
+            new object[] { typeof(double?), 1.0 },
+            new object[] { typeof(double), 1.0 }
+        };
+
+        [Theory]
+        [MemberData(nameof(GreaterThanOrEqualToOneArguments))]
+        public static void GreaterThanOrEqualToOne(Type type, object value)
+        {
+            // two constant of different types that you want to compare
+            Expression x = Expression.Constant(value, type);
+            Expression y = Expression.Constant(1.0f, typeof(float));
+
+            // (T)y -- cast to a common type to allow the comparison later
+            y = Expression.Convert(y, type);
+
+            // (T)y == default(T)
+            Expression guard = Expression.Equal(y, Expression.Default(y.Type));
+
+            // x >= (T)y
+            Expression predicate = Expression.GreaterThanOrEqual(x, y);
+
+            // (T)y == default(T) || x >= (T)y
+            Expression overallExpression = Expression.OrElse(guard, predicate);
+
+            Expression<Func<bool>> lambda = Expression.Lambda<Func<bool>>(overallExpression);
+
+            Assert.True(lambda.Compile(preferInterpretation: false).Invoke());
+            Assert.True(lambda.Compile(preferInterpretation: true).Invoke());
+        }
     }
 }