Do not do macro expansion on preprocessor directive names.

According to the C standards (C17 section 6.10.3 p8), they should not be subject to macro replacement.

A similar change also applies to the "STDC" in #pragma STDC ... (but we still allow macros for other pragmas, which is allowed as part of the implementation-defined behavior of #pragma).

Here is an example affected by this issue:

#define ifdef ifndef
#ifdef foobar
#error "foobar defined?"
#else
int main(void) {}
#endif
This commit is contained in:
Stephen Heumann 2022-10-25 22:40:20 -05:00
parent e0b27db652
commit e63d827049
2 changed files with 11 additions and 0 deletions

View File

@ -3215,7 +3215,9 @@ nextLineNumber := -1;
while charKinds[ord(ch)] = ch_white do {skip white space}
NextCh;
if ch in ['a','d','e','i','l','p','u','w'] then begin
expandMacros := false;
NextToken;
expandMacros := true;
case token.kind of
ifsy: begin
if not tSkipping then
@ -3327,12 +3329,19 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin
'p':
if token.name^ = 'pragma' then begin
if tskipping then goto 2;
expandMacros := false;
NextToken;
expandMacros := true;
if token.class <> identifier then begin
if (lint & lintPragmas) <> 0 then
Error(110);
goto 2;
end; {if}
if token.name^ <> 'STDC' then begin
{Allow macro expansion, other than for STDC }
PutBackToken(token, true);
NextToken;
end; {if}
if token.name^ = 'keep' then
DoKeep
else if token.name^ = 'debug' then begin

View File

@ -1946,6 +1946,8 @@ int foo(int[42]);
215. The digit sequence in the #line directive should be interpreted as a decimal number (not octal) even if it begins with a 0.
216. Preprocessing directive names could be subject to macro replacement, potentially altering their behavior (e.g. due to a definition like "#define ifdef ifndef"). Now directive names are not expanded as macros, even if there is a macro of the same name.
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.