Skip to content

Commit

Permalink
Fix incorrect range comparison for switch operands (dotnet/linker#3128)
Browse files Browse the repository at this point in the history
Commit migrated from dotnet/linker@659f2b6
  • Loading branch information
marek-safar authored Nov 22, 2022
1 parent 1eaf094 commit af6662e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ void RewriteCondition (int index, Instruction instr, int operand)

case Code.Switch:
var targets = (Instruction[]) instr.Operand;
if (operand <= targets.Length) {
if (operand < targets.Length) {
// It does not need to be conditional but existing logic in BodySweeper would
// need to be updated to deal with 1->2 instruction replacement
RewriteConditionTo (index, Instruction.Create (operand == 0 ? OpCodes.Brfalse : OpCodes.Brtrue, targets[operand]));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using Mono.Linker.Tests.Cases.Expectations.Assertions;
using Mono.Linker.Tests.Cases.Expectations.Metadata;
Expand All @@ -17,6 +18,7 @@ public static void Main ()
TestSwitch.TestOffset ();
TestSwitch2.TestFallThrough ();
TestSwitchZero.Test ();
TestSwitch3.TestFallThrough (true);
}

[Kept]
Expand Down Expand Up @@ -125,6 +127,54 @@ public static void TestFallThrough ()
static void Unreached () { }
}

[Kept]
class TestSwitch3
{
[Kept]
[ExpectedInstructionSequence (new[] {
"ldc.i4.4",
"stloc.0",
"ldloc.0",
"pop",
"br.s il_6",
"newobj System.Void System.NotSupportedException::.ctor()",
"throw",
})]
public static object TestFallThrough (bool createReader)
{
object instance;

switch (ProcessArchitecture, createReader) {
case (Architecture.X86, true):
Unreached ();
break;
case (Architecture.X86, false):
Unreached ();
break;
case (Architecture.X64, true):
Unreached ();
break;
case (Architecture.X64, false):
Unreached ();
break;
case (Architecture.Arm64, true):
Unreached ();
break;
case (Architecture.Arm64, false):
Unreached ();
break;
default:
throw new NotSupportedException ();
}

return null;
}

static Architecture ProcessArchitecture => Architecture.Wasm;

static void Unreached () { }
}

[Kept]
class TestSwitchZero
{
Expand Down

0 comments on commit af6662e

Please sign in to comment.