protopopov1122 / kefir

C17 compiler implementation from scratch
63 stars 2 forks source link

Preprocessor # and ## should inhibit expansion #1

Closed ludocode closed 2 years ago

ludocode commented 2 years ago

The preprocessor stringification operator # and token pasting operator ## should inhibit macro expansion of the arguments to which they apply. Only the tokens resulting from the ## operator should be expanded.

Example:

#define foo []
#define cat(x, y) x##y
int cat(foo,_);

The macro foo must not be expanded. Compiling this with gcc -E, clang -E, tcc -E, chibicc -E, MSVC cl /EP, etc. all yield:

int foo_;

With kefir -p (from commit 8952442c1794719057e8ad2b55b810004fbb0f9b) I get the following output:

Failed to compile! Error stack:
No.  Message                                  Class          Subclass   Compiler ref.
  0| a.c@3:13 Expected punctuator token |     Error|            Lexer|  source/preprocessor/user_macro.c:347

If I reverse the arguments to cat, e.g. cat(_,foo), I get this error instead:

Failed to compile! Error stack:
No.  Message                                                          Class          Subclass   Compiler ref.
  0| a.c@3:11 Expected either identifier or preprocessor number |     Error|            Lexer|  source/preprocessor/user_macro.c:207

Another example:

#define foo []
#define stringify(x) #x
const char* f = stringify(foo);

With all other compilers this preprocesses to:

const char* f = "foo";

Preprocessing with kefir -p yields:

const char* f = "[]";

See section 6.10.3.1.1 and sections 6.10.3.3.2-3 in the C17 spec. Macro parameters are substituted and expanded except when they are after # or ## or before ##. Any argument after # is substituted and stringified, not expanded. Any argument before or after ## is substituted, the adjacent tokens are concatenated, and then the resulting tokens are expanded.

Is this the correct place to report bugs? It looks like the project is also on sourcehut. I couldn't find any issue tracker or mailing list there or any other way to report bugs.

protopopov1122 commented 2 years ago

Thank you for reporting the issue. It's indeed a bug and violation of C17 specification. To fix that, I have changed macro argument substitution procedure to avoid argument expansions in # and ## operators. Previously macro arguments were expanded prior to replacement list processing, now expansion happens at the point of argument substitution in replacement list. Added examples from issue description to the test suite.

Regarding bug reporting, issues can be opened on this repo. I have just created basic mailing list and bug tracker on sourcehut, which can be used as well.