Browse Source

Ensure that pattern locals get distinct variable names.

pull/2461/head
Siegfried Pammer 4 years ago
parent
commit
55f1125f94
  1. 4
      ICSharpCode.Decompiler/IL/ILVariable.cs
  2. 1
      ICSharpCode.Decompiler/IL/Transforms/IntroduceNativeIntTypeOnLocals.cs
  3. 23
      ICSharpCode.Decompiler/IL/Transforms/PatternMatchingTransform.cs

4
ICSharpCode.Decompiler/IL/ILVariable.cs

@ -101,6 +101,7 @@ namespace ICSharpCode.Decompiler.IL @@ -101,6 +101,7 @@ namespace ICSharpCode.Decompiler.IL
case VariableKind.ExceptionLocal:
case VariableKind.ForeachLocal:
case VariableKind.UsingLocal:
case VariableKind.PatternLocal:
case VariableKind.PinnedLocal:
case VariableKind.PinnedRegionLocal:
case VariableKind.DisplayClassLocal:
@ -173,6 +174,7 @@ namespace ICSharpCode.Decompiler.IL @@ -173,6 +174,7 @@ namespace ICSharpCode.Decompiler.IL
{
case VariableKind.Local:
case VariableKind.ForeachLocal:
case VariableKind.PatternLocal:
case VariableKind.PinnedLocal:
case VariableKind.PinnedRegionLocal:
case VariableKind.UsingLocal:
@ -541,6 +543,8 @@ namespace ICSharpCode.Decompiler.IL @@ -541,6 +543,8 @@ namespace ICSharpCode.Decompiler.IL
return false;
if (x.Kind == VariableKind.StackSlot || y.Kind == VariableKind.StackSlot)
return false;
if (x.Kind == VariableKind.PatternLocal || y.Kind == VariableKind.PatternLocal)
return false;
if (!(x.Function == y.Function && x.Kind == y.Kind))
return false;
if (x.Index != null)

1
ICSharpCode.Decompiler/IL/Transforms/IntroduceNativeIntTypeOnLocals.cs

@ -36,6 +36,7 @@ namespace ICSharpCode.Decompiler.IL @@ -36,6 +36,7 @@ namespace ICSharpCode.Decompiler.IL
{
if (variable.Kind != VariableKind.Local &&
variable.Kind != VariableKind.StackSlot &&
variable.Kind != VariableKind.PatternLocal &&
variable.Kind != VariableKind.ForeachLocal &&
variable.Kind != VariableKind.UsingLocal)
{

23
ICSharpCode.Decompiler/IL/Transforms/PatternMatchingTransform.cs

@ -19,20 +19,14 @@ @@ -19,20 +19,14 @@
#nullable enable
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using ICSharpCode.Decompiler.CSharp.Resolver;
using ICSharpCode.Decompiler.IL.ControlFlow;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
using static ICSharpCode.Decompiler.TypeSystem.ReflectionHelper;
namespace ICSharpCode.Decompiler.IL.Transforms
{
class PatternMatchingTransform : IILTransform
@ -110,11 +104,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -110,11 +104,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
pos--;
}
if (condition.MatchCompEqualsNull(out var arg))
if (condition.MatchCompEqualsNull(out var loadInNullCheck))
{
ExtensionMethods.Swap(ref trueInst, ref falseInst);
}
else if (condition.MatchCompNotEqualsNull(out arg))
else if (condition.MatchCompNotEqualsNull(out loadInNullCheck))
{
// do nothing
}
@ -122,7 +116,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -122,7 +116,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
return false;
}
if (!arg.MatchLdLoc(out var s))
if (!loadInNullCheck.MatchLdLoc(out var s))
return false;
if (!s.IsSingleDefinition)
return false;
@ -140,8 +134,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -140,8 +134,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
pos--;
if (!block.Instructions[pos].MatchStLoc(s, out value))
return false;
if (!v.IsSingleDefinition)
return false;
if (v.Kind is not (VariableKind.Local or VariableKind.StackSlot))
return false;
if (s.LoadCount != 2)
@ -172,7 +164,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -172,7 +164,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!v.Type.Equals(type))
return false;
if (!CheckAllUsesDominatedBy(v, container, trueInst, storeToV, context, ref cfg))
if (!CheckAllUsesDominatedBy(v, container, trueInst, storeToV, loadInNullCheck, context, ref cfg))
return false;
context.Step($"Type pattern matching {v.Name}", block);
// if (match.type[T].notnull(V = testedOperand)) br trueBlock
@ -191,7 +183,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -191,7 +183,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
private bool CheckAllUsesDominatedBy(ILVariable v, BlockContainer container, ILInstruction trueInst,
ILInstruction storeToV, ILTransformContext context, ref ControlFlowGraph? cfg)
ILInstruction storeToV, ILInstruction? loadInNullCheck, ILTransformContext context, ref ControlFlowGraph? cfg)
{
var targetBlock = trueInst as Block;
if (targetBlock == null && !trueInst.MatchBranch(out targetBlock))
@ -203,12 +195,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -203,12 +195,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
cfg ??= new ControlFlowGraph(container, context.CancellationToken);
var targetBlockNode = cfg.GetNode(targetBlock);
Debug.Assert(v.StoreInstructions.Count == 1);
var uses = v.LoadInstructions.Concat<ILInstruction>(v.AddressInstructions)
.Concat(v.StoreInstructions.Cast<ILInstruction>());
foreach (var use in uses)
{
if (use == storeToV)
if (use == storeToV || use == loadInNullCheck)
continue;
Block? found = null;
for (ILInstruction? current = use; current != null; current = current.Parent)
@ -274,7 +265,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -274,7 +265,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
{
return false;
}
if (!CheckAllUsesDominatedBy(v, container, unboxBlock, storeToV, context, ref cfg))
if (!CheckAllUsesDominatedBy(v, container, unboxBlock, storeToV, null, context, ref cfg))
return false;
context.Step($"PatternMatching with {v.Name}", block);
var ifInst = (IfInstruction)block.Instructions.SecondToLastOrDefault()!;

Loading…
Cancel
Save