# GraalVM — 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:** `compiler/src/`, `truffle/src/`, `substratevm/src/`

## Method

Searched for `isCyclic`, `hasCycle`, `createsCycle`, `isReachable`, `canReach`,
`hasPath`, `detectCycle` across all Java sources. Examined recursive functions
for missing visited-accumulator parameters.

## Key candidates reviewed

### `CFGLoop.isAncestorOrSelf()`
`compiler/src/.../cfg/CFGLoop.java` line 125.

Iterative traversal up a tree via `getParent()` chain — not a DAG traversal. CLEAN.

### `SimpleCyclesIterator.findCyclesInSCG()`
`platform/core-impl/.../graph/impl/SimpleCyclesIterator.java` line 237.

Johnson's algorithm implementation. Uses `myBlocked` (HashSet) as visited/blocked set.
Recursive calls pass `startIndex` and `vertexIndex` for the subgraph indexing.
Full state is tracked in instance fields (`myVIndex`, `myVLowlink`, `myPathSet`). CLEAN.

### Truffle DSL `SpecializationData.getBoundCachesImpl()`
`truffle/src/.../model/SpecializationData.java` line 471.

Signature: `private Set<CacheExpression> getBoundCachesImpl(Set<DSLExpression> visitedExpressions, ...)`

Explicitly takes and uses a `visitedExpressions` Set. CLEAN.

### `BytecodeParser.Target.isReachable()`
`compiler/src/.../java/BytecodeParser.java` line 906.

Returns a stored field — not a graph traversal. CLEAN.

## Verdict

CLEAN for diamond recursion pattern. GraalVM uses `EconomicSet`, `NodeBitMap`,
instance-field visited tracking (Tarjan/Johnson algorithms), and explicit Set
parameters throughout. No unprotected recursive DAG traversal found.
