From ff4812dda8e5b74d1aaf4468bc4589335cd93ab5 Mon Sep 17 00:00:00 2001 From: MCpiroman <38111589+MCpiroman@users.noreply.github.com> Date: Thu, 4 Apr 2019 09:25:16 +0200 Subject: [PATCH] Fix #1462: Inconsistent enum flag check --- .../CSharp/ExpressionBuilder.cs | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs index 220484bf3..5d6a11f30 100644 --- a/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs +++ b/ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2014 Daniel Grunwald +// Copyright (c) 2014 Daniel Grunwald // // Permission is hereby granted, free of charge, to any person obtaining a copy of this // software and associated documentation files (the "Software"), to deal in the Software @@ -699,8 +699,8 @@ namespace ICSharpCode.Decompiler.CSharp } // Special case comparisons with enum and char literals - left = AdjustConstantExpressionToType(left, right.Type); - right = AdjustConstantExpressionToType(right, left.Type); + left = TryUniteEqualityOperandType(left, right); + right = TryUniteEqualityOperandType(right, left); if (IsSpecialCasedReferenceComparisonWithNull(left, right)) { // When comparing a string/delegate with null, the C# compiler generates a reference comparison. @@ -763,6 +763,21 @@ namespace ICSharpCode.Decompiler.CSharp .WithRR(rr); } + TranslatedExpression TryUniteEqualityOperandType(TranslatedExpression operand, TranslatedExpression otherOperand) + { + // 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 (operand.ResolveResult.IsCompileTimeConstant && + operand.ResolveResult.Type.IsCSharpPrimitiveIntegerType() && + (int)operand.ResolveResult.ConstantValue == 0 && + NullableType.GetUnderlyingType(otherOperand.Type).Kind == TypeKind.Enum && + otherOperand.Expression is BinaryOperatorExpression binaryExpr && + binaryExpr.Operator == BinaryOperatorType.BitwiseAnd) + return AdjustConstantExpressionToType(operand, compilation.FindType(KnownTypeCode.Int32)); + else + return AdjustConstantExpressionToType(operand, otherOperand.Type); + } + bool IsSpecialCasedReferenceComparisonWithNull(TranslatedExpression lhs, TranslatedExpression rhs) { if (lhs.Type.Kind == TypeKind.Null)