abhigyanpatwari/GitNexus · warning

[cfg] lang=${provider.language}: ${cdgSkippedUnsound} functi

Error message

[cfg] lang=${provider.language}: ${cdgSkippedUnsound} function(s) had control dependence skipped (EXIT not reverse-reachable from all blocks); CFG and REACHING_DEF are unaffected

What it means

R8 (#2195): when building control dependence (CDG), a function whose EXIT block is not reverse-reachable from every block — an unmodeled non-terminating or multi-terminal CFG shape the synthetic-escape pass could not bridge — gets NO control dependence at all. The skip is surfaced unconditionally per language aggregate; CFG and REACHING_DEF do not depend on post-dominance and remain intact.

Source

Thrown at gitnexus/src/core/ingestion/scope-resolution/pipeline/run.ts:1581

            ? `; taint: ${taintTotals.findings} TAINTED, ${taintTotals.kills} SANITIZES ` +
              `(${taintTotals.analyzed} function(s) analyzed, ` +
              `${taintTotals.noMatch} skipped: no source/sink match` +
              (taintTotals.hopsTruncated > 0
                ? `, ${taintTotals.hopsTruncated} finding(s) with truncated hop paths`
                : '') +
              `)`
            : ''),
      );
    }
    // R8 (#2195): CDG soundness skips surface UNCONDITIONALLY (parity with the
    // taint/RD gap warns) — not buried in the logger.debug stats line above. A
    // function whose EXIT is not reverse-reachable from every block gets NO
    // control dependence (an unmodeled non-terminating / multi-terminal CFG
    // shape the synthetic-escape pass could not bridge). Withholding CDG
    // silently would let a language's control dependence erode unnoticed; CFG
    // and REACHING_DEF do not depend on post-dominance and are unaffected.
    if (cdgSkippedUnsound > 0) {
      logger.warn(
        `[cfg] lang=${provider.language}: ${cdgSkippedUnsound} function(s) had control ` +
          `dependence skipped (EXIT not reverse-reachable from all blocks); ` +
          `CFG and REACHING_DEF are unaffected`,
      );
    }
    // R4: taint coverage gaps and cap drops surface UNCONDITIONALLY (never
    // logger.debug, never input.onWarn) at the per-language aggregate, with
    // counts and up to 5 example functions. Per-function warns above cover
    // the rare/actionable cases (unsafe sites, cap drops); solver-status gaps
    // were already per-function-warned by the RD layer (same solver, same
    // fact cap), so this aggregate is their single taint-side surface.
    if (taintSpec !== undefined) {
      const gapCount =
        taintTotals.unsafeSites +
        taintTotals.gapTruncated +
        taintTotals.gapOverflow +
        taintTotals.gapNoFacts;
      if (gapCount > 0 || taintTotals.dropped > 0) {

View on GitHub (pinned to 0d1aed942f)

Solutions

  1. Confirm scope: only CDG is missing — CFG and REACHING_DEF queries for those functions still answer, so most flows keep working
  2. Locate the functions: the count is aggregate, so correlate with per-function diagnostics or query pdg_query controls on suspects to find which lost CDG
  3. If the shape is your own code (an intentional forever-loop), add an explicit exit path/return so EXIT becomes reverse-reachable and CDG is rebuilt
  4. If the shape looks normal, report it upstream as a CFG-shape modeling gap with the function source

Example fix

# before
async function pump() {
  while (true) {
    await tick();   // EXIT not reverse-reachable → CDG skipped for this fn
  }
}
# after
async function pump(stop: () => boolean) {
  while (!stop()) {
    await tick();   // reachable EXIT → control dependence emitted
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Detect CDG loss before relying on 'controls' queries:
const res = await pdgQuery({ mode: 'controls', target: 'src/worker.ts:pump' });
if (res.results.length === 0 && analyzeLog.includes('control dependence skipped')) {
  // CFG/RD still valid; only control-dependence questions are unanswerable
  console.warn('CDG unavailable for pump — do not treat as no-controls');
}

Prevention

When it happens

Trigger: Running analyze with the PDG layer enabled on code containing functions with pathological terminal shapes (e.g. infinite loops with no path to EXIT, unusual multi-exit structures). cdgSkippedUnsound accumulates across those functions and the warn fires at the per-language aggregate.

Common situations: Embedded/event-loop style code with intentional infinite loops, generated state machines with unreachable exits, or languages whose CFG construction yields blocks that cannot reach EXIT. Users notice it when pdg_query mode 'controls' returns nothing for a function while CFG/RD queries still work.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@0d1aed942f (2026-08-20). Data as JSON: /api/errors/fc23d44bbe347a91. Report an issue: GitHub.