Skip to content

Commit

Permalink
Fix regression in Enum.CompareTo (dotnet#7250)
Browse files Browse the repository at this point in the history
Enum.CompareTo is expected to return -1/0/1, but e.g. `Byte.CompareTo` does not. We can't delegate this.
  • Loading branch information
MichalStrehovsky authored and jkotas committed Apr 3, 2019
1 parent 614fb3b commit 6430354
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions src/System.Private.CoreLib/src/System/Enum.CoreRT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,42 @@ public int CompareTo(object target)
ref byte pThisValue = ref this.GetRawData();
ref byte pTargetValue = ref target.GetRawData();

// Compare the values. Note that we're required to return 0/1/-1 for backwards compat.
switch (this.EETypePtr.CorElementType)
{
case CorElementType.ELEMENT_TYPE_I1:
return Unsafe.As<byte, sbyte>(ref pThisValue).CompareTo(Unsafe.As<byte, sbyte>(ref pTargetValue));
return (Unsafe.As<byte, sbyte>(ref pThisValue) == Unsafe.As<byte, sbyte>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, sbyte>(ref pThisValue) < Unsafe.As<byte, sbyte>(ref pTargetValue)) ? -1 : 1;

case CorElementType.ELEMENT_TYPE_U1:
case CorElementType.ELEMENT_TYPE_BOOLEAN:
return Unsafe.As<byte, byte>(ref pThisValue).CompareTo(Unsafe.As<byte, byte>(ref pTargetValue));
return (Unsafe.As<byte, byte>(ref pThisValue) == Unsafe.As<byte, byte>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, byte>(ref pThisValue) < Unsafe.As<byte, byte>(ref pTargetValue)) ? -1 : 1;

case CorElementType.ELEMENT_TYPE_I2:
return Unsafe.As<byte, short>(ref pThisValue).CompareTo(Unsafe.As<byte, short>(ref pTargetValue));
return (Unsafe.As<byte, short>(ref pThisValue) == Unsafe.As<byte, short>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, short>(ref pThisValue) < Unsafe.As<byte, short>(ref pTargetValue)) ? -1 : 1;

case CorElementType.ELEMENT_TYPE_U2:
case CorElementType.ELEMENT_TYPE_CHAR:
return Unsafe.As<byte, ushort>(ref pThisValue).CompareTo(Unsafe.As<byte, ushort>(ref pTargetValue));
return (Unsafe.As<byte, ushort>(ref pThisValue) == Unsafe.As<byte, ushort>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, ushort>(ref pThisValue) < Unsafe.As<byte, ushort>(ref pTargetValue)) ? -1 : 1;

case CorElementType.ELEMENT_TYPE_I4:
return Unsafe.As<byte, int>(ref pThisValue).CompareTo(Unsafe.As<byte, int>(ref pTargetValue));
return (Unsafe.As<byte, int>(ref pThisValue) == Unsafe.As<byte, int>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, int>(ref pThisValue) < Unsafe.As<byte, int>(ref pTargetValue)) ? -1 : 1;

case CorElementType.ELEMENT_TYPE_U4:
return Unsafe.As<byte, uint>(ref pThisValue).CompareTo(Unsafe.As<byte, uint>(ref pTargetValue));
return (Unsafe.As<byte, uint>(ref pThisValue) == Unsafe.As<byte, uint>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, uint>(ref pThisValue) < Unsafe.As<byte, uint>(ref pTargetValue)) ? -1 : 1;

case CorElementType.ELEMENT_TYPE_I8:
return Unsafe.As<byte, long>(ref pThisValue).CompareTo(Unsafe.As<byte, long>(ref pTargetValue));
return (Unsafe.As<byte, long>(ref pThisValue) == Unsafe.As<byte, long>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, long>(ref pThisValue) < Unsafe.As<byte, long>(ref pTargetValue)) ? -1 : 1;

case CorElementType.ELEMENT_TYPE_U8:
return Unsafe.As<byte, ulong>(ref pThisValue).CompareTo(Unsafe.As<byte, ulong>(ref pTargetValue));
return (Unsafe.As<byte, ulong>(ref pThisValue) == Unsafe.As<byte, ulong>(ref pTargetValue)) ?
0 : (Unsafe.As<byte, ulong>(ref pThisValue) < Unsafe.As<byte, ulong>(ref pTargetValue)) ? -1 : 1;

default:
throw new InvalidOperationException(SR.InvalidOperation_UnknownEnumType);
Expand Down

0 comments on commit 6430354

Please sign in to comment.