Unconditional Recursion
ID |
csharp.unconditional_recursion |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
control-flow, reliability |
Description
Reports methods whose body unconditionally calls themselves with no base case. A method
that recurses on every invocation will overflow the call stack on the first call,
producing a StackOverflowException that aborts the process.
Rationale
Recursive methods are written with two parts: a base case that returns directly, and a
recursive case that calls the method on a smaller problem. When the base case is missing,
the recursive call dominates every path and the method never terminates. This is almost
always a forgotten if guard, a missing decrement, or a copy-paste of an existing
recursive method without adjusting the exit condition.
The rule fires only on the conservative shape "method body is a single recursive call": either an expression statement, a return of the recursive call, or an expression-bodied method. Recursion guarded by a condition is left to a flow-sensitive analysis.
public int Bad(int n) => Bad(n); // FLAW — every call recurses
public void Spin()
{
Spin(); // FLAW — single statement, recursive
}
public int Factorial(int n)
{
if (n <= 1) return 1; // OK — base case present
return n * Factorial(n - 1);
}
Remediation
Add the missing base case. Verify that every recursive path moves the argument toward the base case (typically a decrement or a structural step), and that the base case returns without recursing.