fix: always emit resync linemarker after eval directives#66
fix: always emit resync linemarker after eval directives#66sbryngelson wants to merge 2 commits into
Conversation
Previously, _postprocess_eval_line only emitted a trailing resync
linemarker when the output was either multi-line (span[1] > span[0])
or the last folded continuation line was out-of-sync with the line
counter. This left single-line $: / @: / inline #{...}# calls
without a resync marker.
The missing resync causes silent line-number corruption when the
expanded macro body contains preprocessor conditionals (#ifdef /
#endif). Downstream Fortran preprocessors (e.g. gfortran -cpp) skip
the content of never-taken branches, but the physical source lines
inside those branches still advance the compiler's internal line
counter. Without a resync marker immediately after the expansion,
every subsequent Fortran statement is attributed to the wrong source
line, producing misleading compile-time diagnostics.
Fix: remove the `if unsync or multiline:` guard entirely so that a
resync linemarker is always emitted after every eval directive when
line-number directives are enabled. Update the test suite expected
values to match the new (correct) output, and add a dedicated test
case that exercises the preprocessor-conditional scenario.
ebacec2 to
2cfa96f
Compare
|
For context on real-world impact: this bug affects any project that uses fypp with MFC has deployed a build-time workaround patch (applied to the installed fypp in its virtualenv) while waiting for an upstream fix: MFlowCode/MFC#1436. The workaround works but is obviously not the right long-term solution. Happy to address any review feedback. |
Problem
_postprocess_eval_lineonly emitted a trailing resync linemarker whenunsync or multilinewas true. For single-line$:/@:/ inline#{...}#calls wherespan[0] == span[1]and no continuation foldingoccurred, both flags were
False— so no resync was written.This causes silent line-number corruption whenever the expanded
macro body contains preprocessor conditionals (
#ifdef/#endif).Downstream Fortran preprocessors (e.g.
gfortran -cpp) skip thecontent of never-taken branches, but the physical source lines inside
those branches still advance the compiler's internal line counter.
Without a resync marker immediately after the expansion, every
subsequent statement is attributed to the wrong source line, producing
misleading compile-time diagnostics that point to completely unrelated
code.
Minimal reproducer
Without the fix,
gfortran -fsyntax-only -cppreports errors on thewrong lines because the three physical lines of the skipped
#ifdefblock are not backed out of the compiler's line counter. With the fix,
the resync marker
# 9 "test.fpp"is emitted after the expansion andgfortran lands on the correct line.
Fix
Remove the
if unsync or multiline:guard so a resync linemarker isalways emitted after every eval directive when
--line-numberingis active. The
max(span[1], span[0] + 1)expression that correctlyhandles the
span[0] == span[1]case for inline directives was alreadypresent inside the guard — it just needed to be unconditional.
Tests
LINENUM_TESTS/IncludeTestentries that were previously not expecting the now-always-present
trailing resync.
eval_resync_after_preprocessor_blockthat directlyexercises the macro-with-
#ifdef/#endifbody scenario.test/as theruntests.shscriptrequires, so that include-path relative lookups resolve correctly).