# Kotlin Compiler — 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/frontend/src/`, `compiler/`

## Method

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

## Key candidates reviewed

### `findLoopsInSupertypes.kt — isReachable()`
`compiler/frontend/src/.../resolve/findLoopsInSupertypes.kt` line 56.

Called in a loop (line 40) for each supertype. Each call to `isReachable()` creates
a fresh `DFS.VisitedWithSet()` and performs a full DFS. This is O(S × (V+E)) where
S = supertype count. Not diamond recursion — each call is independent and properly
visits nodes. CLEAN.

### `CyclicAnnotationsChecker`
`compiler/frontend/src/.../resolve/checkers/CyclicAnnotationsChecker.kt`.

`Checker` class maintains instance-level `visitedAnnotationDescriptors` mutableSetOf.
`typeHasCycle()` checks `visitedAnnotationDescriptors.add()` before recursing. CLEAN.

### `NonExpansiveInheritanceRestrictionChecker.kt`
Already addressed by `kotlin-0001-collectreachable-hashset.patch` — the `collectReachable`
function returns a `HashSet` for O(1) membership. Not the diamond recursion pattern.

## Verdict

CLEAN for diamond recursion pattern. Kotlin compiler uses `DFS.VisitedWithSet()`
for all DFS traversal, mutable visited sets for annotation cycle detection,
and existing patches address the unrelated O(N²) List-contains issues.
No unprotected recursive DAG traversal found.
