Browse Source

Enhance null handling in switch transformations

- Updated `Issue3421.cs`.
- Updated `MatchLegacySwitchOnStringWithDict` to check for `leaveContainer` and handle null sections accordingly.
- Introduced an overload for `AddNullSection` to accept `ILInstruction` as the body, improving flexibility.
- Modified existing `AddNullSection` to utilize the new overload, allowing for varied body types in `SwitchSection`.
pull/3422/head
ds5678 5 months ago
parent
commit
e4000c8a5c
  1. 6
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3421.cs
  2. 14
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

6
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/Issue3421.cs

@ -5,10 +5,6 @@ internal class Issue3421
public virtual void SetValue(object value) public virtual void SetValue(object value)
{ {
if (name == null)
{
return;
}
switch (name) switch (name)
{ {
case "##Name##": case "##Name##":
@ -19,6 +15,8 @@ internal class Issue3421
case "##InnerText##": case "##InnerText##":
this.value = value.ToString(); this.value = value.ToString();
return; return;
case null:
return;
} }
if (this.value == null) if (this.value == null)
{ {

14
ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

@ -675,6 +675,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
} }
} }
else if (leaveContainer != null && !defaultBlockJump.MatchLeave(leaveContainer))
{
if (!AddNullSection(sections, stringValues, (Leave)exitBlockJump))
{
return false;
}
}
context.Step(nameof(MatchLegacySwitchOnStringWithDict), instructions[i]); context.Step(nameof(MatchLegacySwitchOnStringWithDict), instructions[i]);
bool keepAssignmentBefore = false; bool keepAssignmentBefore = false;
if (switchValueVar.LoadCount > 2 || switchValue == null) if (switchValueVar.LoadCount > 2 || switchValue == null)
@ -741,6 +748,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} }
bool AddNullSection(List<SwitchSection> sections, List<(string Value, int Index)> stringValues, Block nullValueCaseBlock) bool AddNullSection(List<SwitchSection> sections, List<(string Value, int Index)> stringValues, Block nullValueCaseBlock)
{
return AddNullSection(sections, stringValues, new Branch(nullValueCaseBlock));
}
bool AddNullSection(List<SwitchSection> sections, List<(string Value, int Index)> stringValues, ILInstruction body)
{ {
var label = new LongSet(stringValues.Max(item => item.Index) + 1); var label = new LongSet(stringValues.Max(item => item.Index) + 1);
var possibleConflicts = sections.Where(sec => sec.Labels.Overlaps(label)).ToArray(); var possibleConflicts = sections.Where(sec => sec.Labels.Overlaps(label)).ToArray();
@ -753,7 +765,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
possibleConflicts[0].Labels = possibleConflicts[0].Labels.ExceptWith(label); possibleConflicts[0].Labels = possibleConflicts[0].Labels.ExceptWith(label);
} }
stringValues.Add((null, (int)label.Values.First())); stringValues.Add((null, (int)label.Values.First()));
sections.Add(new SwitchSection() { Labels = label, Body = new Branch(nullValueCaseBlock) }); sections.Add(new SwitchSection() { Labels = label, Body = body });
return true; return true;
} }

Loading…
Cancel
Save