Summary
The graph indexes function calls that occur inside statically-unreachable code as ordinary live CALLS edges. Because the parse is structural (Tree-sitter, no reachability analysis and no C preprocessor evaluation), downstream consumers cannot distinguish a call that can execute from one that never will.
Reproduction (Python)
# consumer.py
from api import process_request
def live_caller():
process_request() # line 5
def dead_caller():
if False: # statically dead
process_request() # line 10 -- never executes
code-review-graph build --skip-flows
Resulting edges (both present):
CALLS consumer.py::dead_caller -> process_request line 10
CALLS consumer.py::live_caller -> process_request line 5
The dead_caller edge should not be presented as a live call.
Reproduction (C/C++)
A call inside a #if 0 ... #endif block is likewise emitted as a live CALLS edge (observed on a real C++ project: a call inside a #if 0 block was indexed identically to the active code path).
Impact
Any consumer doing impact analysis / caller discovery over CALLS edges gets false positives from dead code: "symbol X is called at <dead site>", when that site can never run.
Suggestion
Either (a) skip emitting CALLS edges whose call expression is inside an obviously-dead construct, or (b) tag such edges (e.g. reachable=0 / a "dead-code" confidence_tier) so consumers can filter. The common cheap-to-detect idioms cover most of the value:
- Python:
if False: / if 0: / if TYPE_CHECKING: ; code after an unconditional return/raise/break/continue
- C/C++:
#if 0 ... #endif (and #ifdef of an undefined macro)
Full reachability is undecidable and not expected; handling these common static-dead idioms would remove the bulk of the false positives.
Summary
The graph indexes function calls that occur inside statically-unreachable code as ordinary live CALLS edges. Because the parse is structural (Tree-sitter, no reachability analysis and no C preprocessor evaluation), downstream consumers cannot distinguish a call that can execute from one that never will.
Reproduction (Python)
Resulting edges (both present):
The
dead_calleredge should not be presented as a live call.Reproduction (C/C++)
A call inside a
#if 0 ... #endifblock is likewise emitted as a live CALLS edge (observed on a real C++ project: a call inside a#if 0block was indexed identically to the active code path).Impact
Any consumer doing impact analysis / caller discovery over CALLS edges gets false positives from dead code: "symbol X is called at
<dead site>", when that site can never run.Suggestion
Either (a) skip emitting CALLS edges whose call expression is inside an obviously-dead construct, or (b) tag such edges (e.g.
reachable=0/ a "dead-code"confidence_tier) so consumers can filter. The common cheap-to-detect idioms cover most of the value:if False:/if 0:/if TYPE_CHECKING:; code after an unconditionalreturn/raise/break/continue#if 0 ... #endif(and#ifdefof an undefined macro)Full reachability is undecidable and not expected; handling these common static-dead idioms would remove the bulk of the false positives.