Skip to content

Incorrect paste of placeholder with '##'. #116720

@mrolle45

Description

@mrolle45

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions