From 84fdb5c975683606a66b968de9f40961e764e380 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Thu, 22 Feb 2024 21:55:46 -0600 Subject: [PATCH] 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) --- Scanner.pas | 10 +++++++--- cc.notes | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Scanner.pas b/Scanner.pas index c38f6e8..ccb767a 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -1882,6 +1882,8 @@ procedure Expand (macro: macroRecordPtr); { Globals: } { macroList - scanner putback buffer } +label 1; + type parameterPtr = ^parameterRecord; parameterRecord = record {parameter list element} @@ -2160,8 +2162,10 @@ else begin tcPtr := pptr^.tokens; if tcPtr = nil then begin if tlPtr^.next <> nil then - if tlPtr^.next^.token.kind = poundpoundop then - tlPtr^.next := tlPtr^.next^.next; + if tlPtr^.next^.token.kind = poundpoundop then begin + tlPtr := tlPtr^.next; + goto 1; + end; {if} if lastPtr <> nil then if lastPtr^.token.kind = poundpoundop then if tokenList <> nil then @@ -2213,7 +2217,7 @@ else begin tokenEnd := tlPtr^.tokenEnd; PutBackToken(tlPtr^.token, expandEnabled, false); end; {else} - lastPtr := tlPtr; +1: lastPtr := tlPtr; tlPtr := tlPtr^.next; end; {while} end; {else} diff --git a/cc.notes b/cc.notes index eb0700e..6cfda7f 100644 --- a/cc.notes +++ b/cc.notes @@ -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. +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 --------------------- 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.