Fix handling of empty macro arguments as ## operands.

Previously, there were a couple problems:

*If the parameter that was passed an empty argument appeared directly after the ##, the ## would permanently be removed from the macro record, affecting subsequent uses of the macro even if the argument was not empty.
*If the parameter that was passed an empty argument appeared between two ## operators, both would effectively be skipped, so the tokens to the left of the first ## and to the right of the second would not be combined.

This example illustrates both issues (not expected to compile; just check preprocessor output):

#pragma expand 1
#define x(a,b,c) a##b##c
x(1, ,3)
x(a,b,c)
This commit is contained in:
Stephen Heumann 2024-02-22 21:55:46 -06:00
parent d1847d40be
commit 84fdb5c975
2 changed files with 9 additions and 3 deletions

View File

@ -1882,6 +1882,8 @@ procedure Expand (macro: macroRecordPtr);
{ Globals: } { Globals: }
{ macroList - scanner putback buffer } { macroList - scanner putback buffer }
label 1;
type type
parameterPtr = ^parameterRecord; parameterPtr = ^parameterRecord;
parameterRecord = record {parameter list element} parameterRecord = record {parameter list element}
@ -2160,8 +2162,10 @@ else begin
tcPtr := pptr^.tokens; tcPtr := pptr^.tokens;
if tcPtr = nil then begin if tcPtr = nil then begin
if tlPtr^.next <> nil then if tlPtr^.next <> nil then
if tlPtr^.next^.token.kind = poundpoundop then if tlPtr^.next^.token.kind = poundpoundop then begin
tlPtr^.next := tlPtr^.next^.next; tlPtr := tlPtr^.next;
goto 1;
end; {if}
if lastPtr <> nil then if lastPtr <> nil then
if lastPtr^.token.kind = poundpoundop then if lastPtr^.token.kind = poundpoundop then
if tokenList <> nil then if tokenList <> nil then
@ -2213,7 +2217,7 @@ else begin
tokenEnd := tlPtr^.tokenEnd; tokenEnd := tlPtr^.tokenEnd;
PutBackToken(tlPtr^.token, expandEnabled, false); PutBackToken(tlPtr^.token, expandEnabled, false);
end; {else} end; {else}
lastPtr := tlPtr; 1: lastPtr := tlPtr;
tlPtr := tlPtr^.next; tlPtr := tlPtr^.next;
end; {while} end; {while}
end; {else} end; {else}

View File

@ -1614,6 +1614,8 @@ If you use #pragma debug 0x0010 to enable stack check debug code, the compiler w
12. If a numeric token formed using a ## preprocessor operator was an operand for another ## preprocessor operator, the resulting token would be incorrect. 12. If a numeric token formed using a ## preprocessor operator was an operand for another ## preprocessor operator, the resulting token would be incorrect.
13. If an empty argument was passed for a macro parameter that was used as an operand of the ## preprocessing operator, the result would likely be incorrect, and subsequent uses of the same macro also might not be expanded correctly.
-- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 --------------------- -- Bugs from C 2.1.1 B3 that have been fixed in C 2.2.0 ---------------------
1. There were various bugs that could cause incorrect code to be generated in certain cases. Some of these were specific to certain optimization passes, alone or in combination. 1. There were various bugs that could cause incorrect code to be generated in certain cases. Some of these were specific to certain optimization passes, alone or in combination.