-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Description
If a macro definition contains x ## ## and x is a parameter and the macro is called with an empty argument, then clang ignores the x ## when expanding the macro, leaving just ##. It then tries to paste ## after the preceding token!
To avoid confusion, let paste be a ## token in an odd numbered position in a sequence of ## tokens, and let hashhash be a ## token in an even numbered position in a sequence of ## tokens.
In most cases, clang treats hashhash as an ordinary token, not as a paste operator.
But if x is a parameter for an empty argument, foo x ## bar foo x ## ## bar foo x ## ## ## bar is expanded to foo bar foo ## bar foo ## ## bar. clang interprets this as foo bar foo pastebar foo paste hashhash bar. The result output is foo bar foobar foo ## bar.
Since the first ## got removed, the positions of paste and hashhash are swapped, and clang should produce foo bar foo ## bar foo ## bar.
I verified this result by running clang -E on the file
#define F(x) foo x ## bar foo x ## ## bar foo x ## ## ## bar
F()Suggested fix
Rather than delete the x ## from the expansion, replace it with a new "placeholder" token type. Then follow the Standard rules for pasting with a placeholder, and remove any remaining placeholders after doing the pasting. There will be no cases of consecutive ## tokens
The result output might have an extra '##' in some cases, but it would be consistent with the result for a non-empty macro argument.