⚡ Sangsakala Proxy 🏠 Home
Skip to content

Rescan substituted macro arguments so deferred calls expand like gcc - #713

Open
pfultz2 wants to merge 2 commits into
cppcheck-opensource:masterfrom
pfultz2:pp-eval
Open

pfultz2 wants to merge 2 commits into
cppcheck-opensource:masterfrom
pfultz2:pp-eval

Conversation

@pfultz2

@pfultz2 pfultz2 commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

A function-like macro name that only becomes a call after its neighbours were substituted was never expanded. This fixes #226.

#define EMPTY()
#define EVAL(...) __VA_ARGS__
#define HELLO() "Hello World"
EVAL ( HELLO EMPTY() () )

simplecpp produced HELLO () where gcc and clang produce "Hello World". The same gap broke the DEFER/OBSTRUCT/EVAL idioms (cloak.h style), so iteration macros like REPEAT and WHILE never terminated correctly.

  • Rescan substituted arguments. After an argument is pre-expanded and substituted into the replacement list, the result is rescanned together with the tokens that follow it, so a name followed by a ( that came from a different argument or from the replacement list is expanded as a call.
  • Model the rescan cursor. A new Token::skippedByRescan flag records that the rescan already passed a function-like name without finding (. A ( produced later by another expansion does not turn it into a call, until the token is substituted into a new replacement list and rescanned again. This keeps EVAL(HELLO DEFER(EMPTY)() ()) at HELLO (), matching gcc.
  • One trailing-call loop. expandTrailingCalls is the only place that expands a trailing macro name, with a parameter-aware lookahead for arguments that come from a parameter. Macro::expand marks its own trailing token when a call expanded to nothing, and the argument pre-expansion clears the flag at the substitution point. The flag sits next to whitespaceahead, so sizeof(Token) is unchanged.
  • Common path unchanged. Arguments without any macro name skip the extra rescan.

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.

EVAL(...) not working

1 participant