Browse Source

Fix #2528: arbitrary stores preceding switch-on-string confuse the transform, making it pick the wrong variable as switch variable.

pull/2536/head
Siegfried Pammer 5 years ago
parent
commit
0ed191617e
  1. 18
      ICSharpCode.Decompiler/IL/Transforms/SwitchOnStringTransform.cs

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

@ -548,17 +548,21 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
if (!(condition.MatchCompEquals(out var left, out var right) && right.MatchLdNull())) if (!(condition.MatchCompEquals(out var left, out var right) && right.MatchLdNull()))
return false; return false;
// The initial store can be omitted in some cases. If there is no initial store or the switch value variable is reused later, // Extract switchValueVar
// we do not inline the "switch value", but create an extra load later on. if (!left.MatchLdLoc(out var switchValueVar) || !switchValueVar.IsSingleDefinition)
if (i > 0 && instructions[i - 1].MatchStLoc(out var switchValueVar, out var switchValue)) return false;
// If the switchValueVar is a stack slot and there is an assignment involving it right before the
// switch-value null-check, we use the previously assigned variable as switchValueVar.
ILInstruction switchValue;
if (switchValueVar.Kind == VariableKind.StackSlot
&& instructions.ElementAtOrDefault(i - 1) is StLoc extraStore
&& extraStore.Value.MatchLdLoc(switchValueVar))
{ {
if (!(switchValueVar.IsSingleDefinition && ((SemanticHelper.IsPure(switchValue.Flags) && left.Match(switchValue).Success) || left.MatchLdLoc(switchValueVar)))) switchValueVar = extraStore.Variable;
return false; switchValue = extraStore.Value;
} }
else else
{ {
if (!left.MatchLdLoc(out switchValueVar))
return false;
switchValue = null; switchValue = null;
} }
if (!switchValueVar.Type.IsKnownType(KnownTypeCode.String)) if (!switchValueVar.Type.IsKnownType(KnownTypeCode.String))

Loading…
Cancel
Save