Repository navigation
Conversation
8294236 to
f708fe9
Compare
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 <[email protected]>
…e an error gcc outputs the name, simplecpp reports wrong number of parameters. Co-Authored-By: Claude Opus 5.5 <[email protected]>
f708fe9 to
7ac04ea
Compare
dmcppcheck
left a comment
There was a problem hiding this comment.
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=-Werrorbuilt without warnings../testrunnerpassed with exit code 0 and no failures.python3 run-tests.pypassed: 176 tests, 21 skipped, 15 todos with 0 fixed, 0 failed.python3 -m pytest integration_test.pypassed: 128 tests../selfcheck.shpassed with exit code 0.
The TODO claims, checked against gcc and clang
#define R()/R:gcc -E -PoutputsR, so the wanted value"\nR"with no error is right.cat(a,"s"): gcc (in both C and C++11 mode) reportspasting "a" and ""s"" does not give a valid preprocessing token, and clang reports a similar error. simplecpp outputsa"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.
|
|
||
| static void tokenMacro10() | ||
| { | ||
| // the results of # and ## have no macro name |
There was a problem hiding this comment.
AI review
This comment presents a general rule, but it only holds for function-like macros. In an object-like macro the pasted token keeps the macro name: #define XY x##y / XY gives xy@XY, while cat(x,y) gives xy with an empty macro. A paste that takes part of its text from the body also loses the name: #define cat2(a) a##b / cat2(x) gives xb with macro empty.
cppcheck uses Token::macro to recognise code that comes from a macro. This looks like an inconsistency rather than intended behaviour, so ASSERT_EQUALS would lock it in. I'd use TODO_ASSERT_EQUALS here (or at least a comment that says it is the current behaviour), and add an object-like ## case so that the difference is covered.
No description provided.