Repository navigation
fix(c): a function that writes a macro before a block still uses the macro - #3172
Merged
Merged
Conversation
…macro Regression 4 of the comparison with 1.6.2, from cbd9817 (PR 1736). That commit taught the statement-macro blank to take names in capitals, so that `ATOMIC_BLOCK(x) {` stops reading as a K&R function. The blank takes the whole call, name included, so a function no longer named the macro it uses and its value reference went too: redis lost 10 (`TEST("…") {`, `TEST_CONTEXT`, `TEST_DESC`) and rocksdb 16 (`XXH_ASSERT(c)`, which xxhash writes with no `;`). A change to the macro missed those functions. In a statement of a function body the name now stays, as `name;`, in the bytes the call took. Anywhere else a `;` would be the error the blank avoids: in an initializer, a struct or enum body, another macro's arguments, the rest of an expression, or as the body of an `if`, `for`, `else` or `do`, where it would part the block from its `else` or `while`. Those go whole, as before. cStatementLines reads which lines those are from the file's code, once, and only for a file with such a macro. It is length-preserving and in the preParse, so the kernel gets the same bytes. The arguments stay blanked: a macro's can be types, which a call would not parse, and no call or reference lost against 1.6.2 on redis or rocksdb was in one. Lowercase iterator macros take the same path, so `nk_foreach` in glfw's nuklear.h now counts as used too. Validation against main 4499d00: - Tests: 7 of 9 fail on main, all pass. 11 mutations each fail a test. Three older tests now expect the name to stay. - redis: the 10 are back, nothing lost or moved. rocksdb: 15 of the 16 are back on the same functions. The 16th sat on `XXH3_ACCUMULATE_TEMPLATE(scalar)`, a K&R misreading on both arms whose body is `XXH3_scalarScrambleRound`, which neither arm has as a node; REG read that entry as neither arm's. Two more such phantoms come back with their 4 calls, and 20 locals that had spilled to file scope on main are gone. - glfw +1 (true). jq, leveldb, gin, flask and betaflight: nothing from this commit. - Parse errors over every C file of redis, jq, glfw, betaflight and linux-sub, 10,220 files: 0 worse, 0 better, error counts identical. - Kernel parity, 0 diffs: redis 639/796 (the deferrals main has), jq 66/81, glfw 69/97, rocksdb db+util 381/463, betaflight src 1177/1465. - Cost: C preParse over linux-sub 6.1 to 6.6 s, over redis 1.0 to 1.05 s. cStatementLines is 42 ms of a redis index's profile. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bompus
added a commit
to bompus/codegraph
that referenced
this pull request
Nov 2, 2026
…macro (colbymchenry#3172) Ported from upstream b23c880
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A function that writes a macro before a block, or with no
;after it, counts as using the macro again. This closes regression 4 of the comparison with 1.6.2 (TEST_CONTEXT("…") {on redis) and rocksdb'sXXH_ASSERTreferences.First of a stack of four. The base of this PR is
main.Root cause
cbd9817 (#1736) taught the statement-macro blank to take names in capitals, so that
ATOMIC_BLOCK(x) {stops reading as a K&R function. The blank takes the whole call, name included. The function no longer named the macro, so its value reference went too: 10 on redis, 16 on rocksdb.The fix
In a statement of a function body the name stays, as
name;, in the bytes the call took. Anywhere else a;would be the error the blank avoids, so the call goes whole as before:if,for,elseordo, where it would part the block from itselseorwhile.cStatementLinesreads which lines those are from the file's code, once, and only for a file that has such a macro. The change is length-preserving and in the preParse, so the kernel gets the same bytes and needs no change.The arguments stay blanked. A macro's can be types, which a call would not parse, and no call or reference lost against 1.6.2 on redis or rocksdb was in one. Lowercase iterator macros take the same path, so
nk_foreachin glfw's nuklear.h counts as used too.Validation
Windows 11, main 4499d00.
Tests. 7 of the 9 new tests fail on main and all pass. 11 mutations each fail a test. Three older tests that said the name goes now say it stays (
extraction.test.ts,cpp-raw-string-preparse-1505.test.ts).A/B against main.
nk_convertreally usesnk_foreachThe 16th
XXH_ASSERTsat onXXH3_ACCUMULATE_TEMPLATE(scalar), a K&R misreading on both arms whose body isXXH3_scalarScrambleRound, which neither arm has as a node. REG read that entry as neither arm's.Parse errors. Over every C file of redis, jq, glfw, betaflight and linux-sub, 10,220 files: 0 worse, 0 better, error counts identical.
Kernel parity, 0 diffs. redis 639/796 (the deferrals main has), jq 66/81, glfw 69/97, rocksdb
db+util381/463, betaflightsrc1177/1465.Cost. Whole-index CPU, median of 5 interleaved rounds, base and stack built the same way: redis 23.70 to 23.84 s (+0.6%), wall 7.98 to 7.89 s.
cStatementLinesis 42 ms of a redis index in a profile. C preParse alone: linux-sub 6.1 to 6.6 s, redis 0.94 to 0.99 s.Suite. 857 files passed and 6 skipped, 10,651 tests passed, 2 expected fail, 87 skipped, 4 workers, with the kernel, on the stack one clean rebase back (719ea417 on main 3bd9949). After the rebase onto 087de4c, whose hunks are apart from these: 138 files and 2,224 tests of the C, C++, Objective-C, Python and extraction suites pass on the tip.
🤖 Generated with Claude Code