diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs index a5e5a3bbb..58f53dae9 100644 --- a/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs +++ b/ICSharpCode.Decompiler.Tests/TestCases/Pretty/Switch.cs @@ -1642,7 +1642,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty break; } #if NET40 || !ROSLYN4 - return key != (ConsoleKey)0; + return key != 0; #else return key != ConsoleKey.None; #endif diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index aba6278ac..7f4a5ba82 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1136,21 +1136,36 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(rr); } + TranslatedExpression TryUniteEqualityOperandType(TranslatedExpression left, TranslatedExpression right) { - // Special case for enum flag check "(enum & EnumType.SomeValue) == 0" - // so that the const 0 value is printed as 0 integer and not as enum type, e.g. EnumType.None if (left.ResolveResult.IsCompileTimeConstant && left.ResolveResult.Type.IsCSharpPrimitiveIntegerType() && (left.ResolveResult.ConstantValue as int?) == 0 && - NullableType.GetUnderlyingType(right.Type).Kind == TypeKind.Enum && - right.Expression is BinaryOperatorExpression binaryExpr && - binaryExpr.Operator == BinaryOperatorType.BitwiseAnd) + AvoidConvertingZeroToEnum(right)) { return AdjustConstantExpressionToType(left, compilation.FindType(KnownTypeCode.Int32)); } else return AdjustConstantExpressionToType(left, right.Type); + + static bool AvoidConvertingZeroToEnum(TranslatedExpression right) + { + var enumType = NullableType.GetUnderlyingType(right.Type); + if (enumType.Kind != TypeKind.Enum) + return false; + // Special case for enum flag check "(enum & EnumType.SomeValue) == 0" + // so that the const 0 value is printed as 0 integer and not as enum type, e.g. EnumType.None + if (right.Expression is BinaryOperatorExpression { Operator: BinaryOperatorType.BitwiseAnd }) + { + return true; + } + // Don't use a cast `if (e == (EnumType)0)`, prefer using the integer 0 directly. + bool hasZero = (enumType.GetDefinition() is { } typeDef && + typeDef.Fields.Any(f => f.GetConstantValue() is { } val + && (ulong)CSharpPrimitiveCast.Cast(TypeCode.UInt64, val, false) == 0L)); + return !hasZero; + } } bool IsSpecialCasedReferenceComparisonWithNull(TranslatedExpression lhs, TranslatedExpression rhs)