# Eclipse JDT — Diamond Recursion CWE-407 Scan: CLEAN

**Pattern:** Recursive cycle/reachability without visited set (O(2^D) on diamond DAGs)
**Scan date:** 2026-03-29
**Scope:** `org.eclipse.jdt.core/`, `org.eclipse.jdt.core.compiler.batch/`

## Method

Searched for `hasCycle`, `isCyclic`, `isReachable`, `canReach`, `hasPath`,
`detectCycle` across all Java sources. Examined each recursive function for
a missing visited-accumulator parameter.

## Key candidates reviewed

### `ClassScope.detectHierarchyCycle()`
`org.eclipse.jdt.core.compiler.batch/.../lookup/ClassScope.java` line 1474.

Recursive — calls itself at lines 1517 and 1535. However, it avoids diamond
blowup via per-node memoization embedded in `TagBits`:
- Sets `TagBits.BeginHierarchyCheck` on each node before descending
- Checks `isHierarchyBeingActivelyConnected()` (an IN_PROGRESS flag) before recursing
- Checks `(superType.tagBits & TagBits.BeginHierarchyCheck) == 0` to skip already-visited nodes
- For binary supertypes, propagates `TagBits.HierarchyHasProblems` upward to avoid re-expansion

This is a "colored node" visited-set pattern where the visited state lives on the
node object itself rather than in an external set. Equivalent complexity to DFS
with a visited set — O(V+E). Not the diamond recursion anti-pattern.

### `InferenceContext18.isReachable()`
`org.eclipse.jdt.core.compiler.batch/.../lookup/InferenceContext18.java` line 1688.

Signature: `private boolean isReachable(Map<ConstraintFormula,Set<ConstraintFormula>> deps, ConstraintFormula from, ConstraintFormula to, Set<ConstraintFormula> nodesVisited, Set<ConstraintFormula> nodesInCycle)`

Explicitly takes a `nodesVisited` set parameter — `nodesVisited.add(from)` at line 1695
is the visited guard. CLEAN.

### `ModuleBinding.collectAllDependencies()` / `collectTransitiveDependencies()`
`org.eclipse.jdt.core.compiler.batch/.../lookup/ModuleBinding.java` lines 419, 426.

Uses `deps.add(m)` — the Set parameter itself is the visited accumulator. If `add()`
returns false (already present), the recursive call is skipped. CLEAN.

## Verdict

CLEAN for diamond recursion pattern. Eclipse JDT uses either per-node TagBits
memoization or explicit Set parameters to prevent diamond blowup. No unprotected
recursive DAG traversal found.
