diff --git a/ICSharpCode.Decompiler/FlowAnalysis/DataFlowVisitor.cs b/ICSharpCode.Decompiler/FlowAnalysis/DataFlowVisitor.cs
index a43ac19e6..ed5d01918 100644
--- a/ICSharpCode.Decompiler/FlowAnalysis/DataFlowVisitor.cs
+++ b/ICSharpCode.Decompiler/FlowAnalysis/DataFlowVisitor.cs
@@ -646,6 +646,8 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
} else {
return (state, bottomState.Clone());
}
+ } else if (inst is MatchInstruction match) {
+ return EvaluateMatch(match);
} else {
// other kind of condition
inst.AcceptVisitor(this);
@@ -653,6 +655,45 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
}
}
+ protected internal override void VisitMatchInstruction(MatchInstruction inst)
+ {
+ var (onTrue, onFalse) = EvaluateMatch(inst);
+ state = onTrue;
+ state.JoinWith(onFalse);
+ }
+
+ ///
+ /// Evaluates a match instruction.
+ ///
+ ///
+ /// A pair of:
+ /// * The state after the pattern matches
+ /// * The state after the pattern fails to match
+ ///
+ ///
+ /// this.state is invalid after this function was called, and must be overwritten
+ /// with one of the return values.
+ ///
+ (State OnTrue, State OnFalse) EvaluateMatch(MatchInstruction inst)
+ {
+ DebugStartPoint(inst);
+ inst.TestedOperand.AcceptVisitor(this);
+ State onFalse = state.Clone();
+ if (!inst.CheckNotNull && !inst.CheckType) {
+ onFalse.ReplaceWithBottom();
+ }
+ HandleMatchStore(inst);
+ foreach (var subPattern in inst.SubPatterns) {
+ var (subTrue, subFalse) = EvaluateCondition(subPattern);
+ onFalse.JoinWith(subFalse);
+ state = subTrue;
+ }
+ DebugEndPoint(inst);
+ return (state, onFalse);
+ }
+
+ protected abstract void HandleMatchStore(MatchInstruction inst);
+
protected internal override void VisitNullCoalescingInstruction(NullCoalescingInstruction inst)
{
HandleBinaryWithOptionalEvaluation(inst, inst.ValueInst, inst.FallbackInst);
diff --git a/ICSharpCode.Decompiler/FlowAnalysis/DefiniteAssignmentVisitor.cs b/ICSharpCode.Decompiler/FlowAnalysis/DefiniteAssignmentVisitor.cs
index 5b465b735..726cef1f7 100644
--- a/ICSharpCode.Decompiler/FlowAnalysis/DefiniteAssignmentVisitor.cs
+++ b/ICSharpCode.Decompiler/FlowAnalysis/DefiniteAssignmentVisitor.cs
@@ -168,7 +168,12 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
inst.Value.AcceptVisitor(this);
HandleStore(inst.Variable);
}
-
+
+ protected override void HandleMatchStore(MatchInstruction inst)
+ {
+ HandleStore(inst.Variable);
+ }
+
protected override void BeginTryCatchHandler(TryCatchHandler inst)
{
HandleStore(inst.Variable);
diff --git a/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs b/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs
index 8b6d22a24..08bf2e4f2 100644
--- a/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs
+++ b/ICSharpCode.Decompiler/FlowAnalysis/ReachingDefinitionsVisitor.cs
@@ -380,7 +380,12 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
inst.Value.AcceptVisitor(this);
HandleStore(inst, inst.Variable);
}
-
+
+ protected override void HandleMatchStore(MatchInstruction inst)
+ {
+ HandleStore(inst, inst.Variable);
+ }
+
protected override void BeginTryCatchHandler(TryCatchHandler inst)
{
base.BeginTryCatchHandler(inst);