Skip to content

fix(uninitialized): a stopped callee in the same file counts as a declaration - #196

Merged
SizzleUnrlsd merged 2 commits into
mainfrom
168-uninit-non-converged-summary
Oct 8, 2026
Merged

SizzleUnrlsd merged 2 commits into
mainfrom
168-uninit-non-converged-summary

Conversation

@SizzleUnrlsd

@SizzleUnrlsd SizzleUnrlsd commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #168

Problem

When the dataflow of a function stops at its iteration budget, its summary is marked incomplete. Since #157, an imported incomplete summary is absent for its effects. In the same file, callers still applied it:

  • a write downgraded to "unknown write" did not mark the local as initialized, so a later read was reported (false positive);
  • a parameter without effect was read as "reads and writes nothing".

Reproduced by forcing a budget of 2 iterations on callees whose blocks are laid out before their predecessors:

Callee Converged Budget 2 on main Callee as a declaration
writes *p on every path no diagnostic UninitializedLocalRead on the caller's read (false positive) no diagnostic
reads *p read through the call reported never initialized instead no diagnostic

Fix

As the cross-TU design prescribes (§4.1, §5.2, §11), an incomplete summary defined in the same module is now absent for its effects, as an imported one is. The call gets the presumption for declarations (§5.1), not the fallback for defined functions without a summary, which keeps the false positive. An asDeclaration flag goes through the six helpers of that presumption, which tested callee->isDeclaration(). The caller stays incomplete, as before.

Tests

  • New input test/unit/uninit_incomplete_same_file.c and test testUninitializedIncompleteSummariesInOneFile. With a budget of 2, the callees report AnalysisIncomplete, and each caller must report exactly what its twin calling a declaration reports. Guards cover the converged results and the completeness of the callers.
  • RED on main: the 2 comparisons fail. GREEN: 7/7, no unit test failure.
  • Mutants caught: dropping the summary without the declaration presumption, and keeping the same-file summary.
  • CI-like suite on Linux x86_64: 2384/2384, unit tests included.

Before / after (main db0c4fe vs this branch, Linux x86_64)

  • Fixtures, default and z3: 846 runs, 0 differ, 1287 = 1287 diagnostics.
  • Self-analysis, 4 chunks: 71 = 71 diagnostics, 0 differ.

The change only acts when a dataflow does not converge, which does not happen with the automatic budget on these corpora.

Limits

  • The libc-name rules of the declaration presumption (write/send sinks, memcpy-like transfers) now also apply to a same-file callee with an incomplete summary. No test covers them.

Code scanning

CI is green on 50b648f: 13 checks pass, the release attach step is skipped.

  • 66 open alerts on the merge ref, the same numbers as on main: none new, none gone.
  • No github-advanced-security comment on this PR. No new coretrace-concurrency-analyzer alert.
  • This matches the local self-analysis before/after: 71 = 71 results, 0 differ.

…a declaration

A summary from a dataflow stopped before its fixpoint is absent for its
effects only when it is imported (#168). In the same file, its callers
still apply it: a write turned into an unknown write leaves the local
uninitialized, and a parameter without effect reads as "no effect".

With a budget of two iterations, a call to such a callee must report
what a call to a declaration reports.
…laration

A summary from a dataflow stopped before its fixpoint was absent for its
effects only when imported. In the same file its callers still applied
it: a write downgraded to an unknown write left the local uninitialized,
so a later read was reported, and a parameter without effect read as
"no effect".

Treat it as absent there too, as the cross-TU design prescribes (§4.1):
the call gets the presumption for declarations, not the fallback for
defined functions without a summary. The caller stays incomplete.

Fixes #168
@SizzleUnrlsd SizzleUnrlsd added the bug Something isn't working label Oct 8, 2026
@SizzleUnrlsd SizzleUnrlsd self-assigned this Oct 8, 2026
@SizzleUnrlsd
SizzleUnrlsd merged commit faf1050 into main Oct 8, 2026
14 checks passed
@SizzleUnrlsd
SizzleUnrlsd deleted the 168-uninit-non-converged-summary branch October 8, 2026 21:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UninitializedLocalRead: a summary from a non-converged dataflow is used as complete in the same file

1 participant