diff --git a/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs b/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs
index 66f431809e..21ec3becd7 100644
--- a/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs
+++ b/ICSharpCode.Decompiler/IL/Transforms/ReduceNestingTransform.cs
@@ -254,7 +254,9 @@ private bool ReduceNesting(Block block, IfInstruction ifInst, ILInstruction exit
ifInst = elseIfInst;
}
- if (!ShouldReduceNesting(ifInst.FalseInst, maxStatements, maxDepth))
+ // A chain with no trailing else has no block to reduce: ifInst.FalseInst is a bare Nop.
+ // Guarding here keeps the else-block cast in ExtractElseBlock safe (#3891).
+ if (ifInst.FalseInst is not Block falseBlock || !ShouldReduceNesting(falseBlock, maxStatements, maxDepth))
return false;
// extract the else block and insert exit points all the way up the else-if tree
@@ -582,16 +584,16 @@ private void ComputeStats(ILInstruction inst, ref int numStatements, ref int max
///
/// Heuristic to determine whether it is worth duplicating exits into the preceeding sibling blocks (then/else-if/case)
- /// in order to reduce the nesting of inst by 1
+ /// in order to reduce the nesting of block by 1
///
- /// The instruction heading the nested candidate block
+ /// The nested candidate block (an else or default block)
/// The number of statements in the largest sibling block
/// The relative depth of the most nested statement in the sibling blocks
///
- private bool ShouldReduceNesting(ILInstruction inst, int maxStatements, int maxDepth)
+ private bool ShouldReduceNesting(Block block, int maxStatements, int maxDepth)
{
int maxStatements2 = 0, maxDepth2 = 0;
- UpdateStats(inst, ref maxStatements2, ref maxDepth2);
+ UpdateStats(block, ref maxStatements2, ref maxDepth2);
// if the max depth is 2, always reduce nesting (total depth 3 or more)
// if the max depth is 1, reduce nesting if this block is the largest
// otherwise reduce nesting only if this block is twice as large as any other