Created
June 12, 2019 14:21
-
-
Save arlm/da7cb15b22dcbd231852c55b38038ca5 to your computer and use it in GitHub Desktop.
Bool Convert (IL Conv_I1) bug
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Reflection.Emit; | |
namespace BoolConvertBug | |
{ | |
public class Program | |
{ | |
public static void Main(string[] args) | |
{ | |
Func<int, bool> func = CreateDynamicMethod(); | |
Console.WriteLine( "\n================ conv.i1 (1) ================" ); | |
IsTrueBool(func(1)); | |
IsTrue(func(1)); | |
Console.WriteLine( "\n================ conv.i1 (2) ================" ); | |
IsTrueBool(func(2)); | |
IsTrue(func(2)); | |
Console.WriteLine( "\n================ conv.i1 (0) ================" ); | |
IsFalseBool(func(0)); | |
IsFalse(func(0)); | |
Console.WriteLine( "\n================ conv.i1 (-1) ================" ); | |
IsFalseBool(func(-1)); | |
IsFalse(func(-1)); | |
} | |
private static void IsFalseBool(bool actual) | |
{ | |
Console.WriteLine( $"\n\n[bool] bool actual parameter = {actual}" ); | |
var value = System.Convert.ToBoolean(actual); | |
Console.WriteLine( "[bool] var value = System.Convert.ToBoolean(actual)" ); | |
bool @false = false; | |
Console.WriteLine( "[bool] var @false = false;" ); | |
bool test1 = false.Equals(false); | |
Console.WriteLine($"[bool] false.Equals(false) = {test1}"); | |
bool test2 = false.Equals(@false); | |
Console.WriteLine($"[bool] false.Equals(@false) = {test2}"); | |
bool isSuccess = false.Equals(value); | |
Console.WriteLine($"[bool] false.Equals(value) = {isSuccess}"); | |
bool isSuccess2 = false.Equals(value && true); | |
Console.WriteLine($"[bool] false.Equals(value && true) = {isSuccess2}"); | |
} | |
private static void IsFalse<TActual>(TActual actual) | |
{ | |
Console.WriteLine( $"\n\n[<TActual>] bool actual parameter = {actual}" ); | |
var value = System.Convert.ToBoolean(actual); | |
Console.WriteLine( "[<TActual>] var value = System.Convert.ToBoolean(actual)" ); | |
bool @false = false; | |
Console.WriteLine( "[<TActual>] var @false = false;" ); | |
bool test1 = false.Equals(false); | |
Console.WriteLine($"[<TActual>] false.Equals(false) = {test1}"); | |
bool test2 = false.Equals(@false); | |
Console.WriteLine($"[<TActual>] false.Equals(@false) = {test2}"); | |
bool isSuccess = false.Equals(value); | |
Console.WriteLine($"[<TActual>] false.Equals(value) = {isSuccess}"); | |
bool isSuccess2 = false.Equals(value && true); | |
Console.WriteLine($"[<TActual>] false.Equals(value && true) = {isSuccess2}"); | |
} | |
private static void IsTrueBool(bool actual) | |
{ | |
Console.WriteLine( $"\n\n[bool] bool actual parameter = {actual}" ); | |
var value = System.Convert.ToBoolean(actual); | |
Console.WriteLine( "[bool] var value = System.Convert.ToBoolean(actual)" ); | |
bool @true = true; | |
Console.WriteLine( "[bool] var @true = true;" ); | |
bool test1 = true.Equals(true); | |
Console.WriteLine($"[bool] true.Equals(true) = {test1}"); | |
bool test2 = true.Equals(@true); | |
Console.WriteLine($"[bool] true.Equals(@true) = {test2}"); | |
bool isSuccess = true.Equals(value); | |
Console.WriteLine($"[bool] true.Equals(value) = {isSuccess}"); | |
bool isSuccess_ = true.Equals((object)value); | |
Console.WriteLine($"[bool] true.Equals((object)value) = {isSuccess_}"); | |
bool isSuccess2 = true.Equals(value && true); | |
Console.WriteLine($"[bool] true.Equals(value && true) = {isSuccess2}"); | |
bool isSuccess3 = true == value; | |
Console.WriteLine($"[bool] true == value = {isSuccess3}"); | |
bool isSuccess3_ = (object)true == (object)value; | |
Console.WriteLine($"[bool] (object)true == (object)value = {isSuccess3_}"); | |
bool isSuccess4 = true == value && true; | |
Console.WriteLine($"[bool] true == value && true = {isSuccess4}"); | |
bool isSuccess5 = value == true; | |
Console.WriteLine($"[bool] value == true = {isSuccess5}"); | |
bool isSuccess6 = value && true == true; | |
Console.WriteLine($"[bool] value && true == true = {isSuccess6}"); | |
} | |
private static void IsTrue<TActual>(TActual actual) | |
{ | |
Console.WriteLine( $"\n\n[<TActual>] bool actual parameter = {actual}" ); | |
var value = System.Convert.ToBoolean(actual); | |
Console.WriteLine( "[<TActual>] var value = System.Convert.ToBoolean(actual)" ); | |
bool @true = true; | |
Console.WriteLine( "[<TActual>] var @true = true;" ); | |
bool test1 = true.Equals(true); | |
Console.WriteLine($"[<TActual>] true.Equals(true)= {test1}"); | |
bool test1_ = true.Equals((object)value); | |
Console.WriteLine($"[<TActual>] true.Equals((object)value) = {test1_}"); | |
bool test2 = true.Equals(@true); | |
Console.WriteLine($"[<TActual>] true.Equals(@true) = {test2}"); | |
bool isSuccess = true.Equals(value); | |
Console.WriteLine($"[<TActual>] true.Equals(value) = {isSuccess}"); | |
bool isSuccess2 = true.Equals(value && true); | |
Console.WriteLine($"[<TActual>] true.Equals(value && true) = {isSuccess2}"); | |
} | |
private static Func<int, bool> CreateDynamicMethod() | |
{ | |
var methodArgs = new Type[] { typeof(int) }; | |
var convert = new DynamicMethod("TestMethod", typeof(bool), methodArgs, typeof(Program).Module); | |
var il = convert.GetILGenerator(); | |
il.Emit(OpCodes.Ldarg_0); | |
il.Emit(OpCodes.Conv_I1); | |
il.Emit(OpCodes.Ret); | |
var @delegate = convert.CreateDelegate(typeof(Func<int, bool>)); | |
return @delegate as Func<int, bool>; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment