findAndVerifyWindowGrace() recurses over parent GraphNodes without a visited accumulator. Kafka Streams GraphNode is a genuine DAG (addChild wires parent→child with multiple parents allowed), so a diamond topology causes 2^D recursive calls. Fix: thread an IdentityHashMap<GraphNode,Long> memo through recursion; memoize on first visit, return cached result on revisit. 8/8 unit tests PASS; D=10 defect count=3071 vs patched O(N). Diamond-recursion CLEAN markers added for: flink, neo4j, janusgraph, tinkerpop, dgraph, zookeeper, storm, ant, gradle, graal, eclipse-jdt, exposed, intellij, kotlin, scala3, hibernate-0007 (prior session work now committed).
1.7 KiB
Scala 3 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/src/dotty/
Method
Searched for isCyclic, hasCycle, createsCycle, isReachable, canReach,
hasPath, detectCycle across all Scala sources. Examined recursive functions
for missing visited-accumulator parameters.
Key candidates reviewed
SymDenotations.computeBaseType() — recur() inner function
compiler/src/dotty/tools/dotc/core/SymDenotations.scala around line 2265.
recur(tp) is called recursively but uses btrCache as a memoization cache.
Before recursing, it checks btrCache.lookup(tp) for a sentinel value (NoPrefix)
that indicates a cycle in progress. This is a memo-table anti-cycle pattern. CLEAN.
OrderingConstraint.dependsOn()
compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala line 286.
Uses deps.at(param).exists(qualifies) — direct set lookup, not recursive. CLEAN.
Checking.CheckNonCyclicMap
compiler/src/dotty/tools/dotc/typer/Checking.scala line 257.
CheckNonCyclicMap extends TypeMap and uses a cycleOK flag plus
CyclicReference exception for cycle detection. Not diamond recursion — uses
exception-based unwinding, not unbounded recursion. CLEAN.
SymUtils.isReachable
compiler/src/dotty/tools/dotc/core/SymUtils.scala line 211.
Returns ctx.owner.isContainedIn(sym) — single O(depth) tree traversal.
Not a DAG traversal. CLEAN.
Verdict
CLEAN for diamond recursion pattern. Scala 3 compiler uses btrCache memo tables,
exception-based cycle detection, and O(depth) tree traversals. No unprotected
recursive DAG traversal found.