Skip to content

Keep a symbol free when a state reads it before any assignment - #2712

Merged
tbennun merged 6 commits into
spcl:mainfrom
ThrudPrimrose:fix-free-symbols-read-before-assignment
Oct 20, 2026
Merged

tbennun merged 6 commits into
spcl:mainfrom
ThrudPrimrose:fix-free-symbols-read-before-assignment

Conversation

@ThrudPrimrose

@ThrudPrimrose ThrudPrimrose commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

A symbol read before any interstate edge assigns it, or after a join where only some branches assigned it, now stays in free_symbols, so callers are asked for it. Branches start from the entry definitions and track maybe-assigned symbols as tentative; five tests in tests/sdfg/free_symbols_test.py cover state, loop, branch, all-paths and C++-local cases.

Motivating example:

#     if a[0] > 0:  k = 1
#     out[0] = k

k is a free symbol because it is not unconditionally assigned, this would make k a non-free symbol:

#     if a[0] > 0:
#        k = 1
#     else:
#        k = 0
#     out[0] = k

A state that reads k before any interstate edge assigns it never recorded k as
used before assignment, so a later k = ... marked k defined and dropped it from
free_symbols.
A ConditionalBlock now reports the symbols only some paths assign as tentative: a later read of one counts as a
use before assignment, while a symbol assigned in one branch and never read stays out of the signature. Branches
start from the entry definitions instead of their siblings'. Adds tests for a loop body read, a one-branch
assignment, an assignment on every path and a C++ local listed in ignored_symbols.
@ThrudPrimrose
ThrudPrimrose requested a review from tbennun October 20, 2026 08:36
@tbennun
tbennun added this pull request to the merge queue Oct 20, 2026
Merged via the queue into spcl:main with commit 00381e5 Oct 20, 2026
17 checks passed
ThrudPrimrose added a commit that referenced this pull request Oct 20, 2026
…read before assignment

Extended already carries #2706 as a port (41640a3, f1747c3) and its own free_symbols walk, so each
conflict keeps extended's side; from main it takes the program-callable modulo spellings (PyMod,
FtnMod, FtnModulo through operators.MODULO_CALLS and binop_tasklet_code) and main's tests. Two of
main's modulo tests are adapted to extended's documented semantics: a CMod of operands not proven
integer prints as c_mod, and sign facts of a dace.symbol live in the symbol registry, so the
CMod->Mod fold is checked on SymPy symbols with assumptions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants