Browse Source

Merge pull request #1476 from mcpiroman/issue-1462

Fix #1462: Inconsistent enum flag check
pull/1515/head
Siegfried Pammer 6 years ago committed by GitHub
parent
commit
ef42ff8789
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs
  2. 22
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

10
ICSharpCode.Decompiler.Tests/TestCases/Pretty/ConstantsTests.cs

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
using System.Threading.Tasks;
namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
{
internal class ConstantsTests
{
@ -24,6 +26,12 @@ @@ -24,6 +26,12 @@
Test((v | 0x123) == 0);
}
public void Enum_Flag_Check(TaskCreationOptions v)
{
Test((v & TaskCreationOptions.AttachedToParent) != 0);
Test((v & TaskCreationOptions.AttachedToParent) == 0);
}
private void Test(bool expr)
{
}

22
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -1,4 +1,4 @@ @@ -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 @@ -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,22 @@ namespace ICSharpCode.Decompiler.CSharp @@ -763,6 +763,22 @@ 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)
{
return AdjustConstantExpressionToType(left, compilation.FindType(KnownTypeCode.Int32));
} else
return AdjustConstantExpressionToType(left, right.Type);
}
bool IsSpecialCasedReferenceComparisonWithNull(TranslatedExpression lhs, TranslatedExpression rhs)
{
if (lhs.Type.Kind == TypeKind.Null)

Loading…
Cancel
Save