Skip to content

Fix #744 (Add regression tests for macro expansion) - #745

Merged
danmar merged 2 commits into
masterfrom
pr-macro-regression-tests
Nov 9, 2026
Merged

danmar merged 2 commits into
masterfrom
pr-macro-regression-tests

Conversation

@danmar

@danmar danmar commented Nov 8, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@danmar
danmar force-pushed the pr-macro-regression-tests branch from 8294236 to f708fe9 Compare November 9, 2026 00:28
dmcppcheck and others added 2 commits November 9, 2026 01:41
C11 6.10.3.5 examples 3, 4, 5 and 7, the C23 __VA_OPT__ examples and invalid
## pastes. Known bugs are tested with the new TODO_ASSERT_EQUALS.

Tests for Token::macro, the locations of expanded tokens and the macro usage,
which are used by cppcheck. A new helper expandedTokens() writes each output
token with its macro name and location; the tokenMacro tests use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e an error

gcc outputs the name, simplecpp reports wrong number of parameters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@danmar
danmar force-pushed the pr-macro-regression-tests branch from f708fe9 to 7ac04ea Compare November 9, 2026 00:42

@dmcppcheck dmcppcheck left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI review

The PR only changes test.cpp. All tests pass, and I checked every TODO comment's claim against gcc and clang (the R/X name at the end of the file, the empty token from r(,)/t(,,), ==0 after the comment, a"s" should be an error). Each claim is correct, and every "wanted" value matches the reference preprocessors.

There is one new finding. tokenMacro10 uses ASSERT_EQUALS to lock in empty Token::macro for the results of # and ##, and its comment presents that as a general rule. It only holds for function-like macros. Object-like macros give the pasted token the macro name (#define XY x##y gives xy@XY). So does a function-like macro whose pasted token is built from body text, as in cat2(x) → xb with an empty name. cppcheck uses this field, so this looks like a known gap that should be a TODO, not a rule. I found no other problems.

Testing

Build and test suites

  • make -j8 testrunner simplecpp CXXOPTS=-Werror built without warnings.
  • ./testrunner passed with exit code 0 and no failures.
  • python3 run-tests.py passed: 176 tests, 21 skipped, 15 todos with 0 fixed, 0 failed.
  • python3 -m pytest integration_test.py passed: 128 tests.
  • ./selfcheck.sh passed with exit code 0.

The TODO claims, checked against gcc and clang

  • #define R() / R: gcc -E -P outputs R, so the wanted value "\nR" with no error is right.
  • cat(a,"s"): gcc (in both C and C++11 mode) reports pasting "a" and ""s"" does not give a valid preprocessing token, and clang reports a similar error. simplecpp outputs a"s" with no error.
  • { r(,) }: gcc outputs { }. simplecpp outputs { }, with an empty token between the braces.
  • The str(strncmp(...) // this goes away\n == 0) example: gcc gives ... '\\4') == 0". simplecpp gives '\\4') ==0".

Token::macro for # and ## results

I linked a small program against simplecpp.o and printed str@macro for each output token:

#define str(x) #x
#define XY x##y
#define cat(a,b) a##b
#define cat2(a) a##b
XY cat(x,y) cat2(x) str(z)

Output: xy@XY xy@ xb@ "z"@. The object-like macro keeps its macro name on the pasted token. In the function-like macros the name is empty, even for xb, which is pasted with the body token b.


Automated review of 7ac04ea by Claude. The pull request was built and tested locally.

Comment thread test.cpp Resolved
@danmar
danmar merged commit c137175 into master Nov 9, 2026
47 checks passed
@danmar
danmar deleted the pr-macro-regression-tests branch November 9, 2026 07:50
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