From 7ab1875b540f74380312514ae29ab1636f76185b Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 20 Dec 2016 20:30:05 -0600 Subject: [PATCH] Evaluate preprocessor expressions using 32-bit long/unsigned long types. This is as required by C90. C99 and later require (u)intmax_t, which must be 64-bit or greater. The following example shows problems with the previous behavior: #if (30000 + 30000 == 60000) && (1 << 16 == 0x10000) int main(void) {} #else #error "preprocessor error" #endif --- Expression.pas | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Expression.pas b/Expression.pas index e28e5d6..d7b3ebf 100644 --- a/Expression.pas +++ b/Expression.pas @@ -924,6 +924,20 @@ var end; {IntVal} + function PPKind (token: tokenType): tokenEnum; + + { adjust kind of token for use in preprocessor expression } + + begin {PPKind} + if token.kind = intconst then + PPKind := longconst + else if token.kind = uintconst then + PPKind := ulongconst + else + PPKind := token.kind; + end; {PPKind} + + begin {Operation} op := opStack; {pop the operation} opStack := op^.next; @@ -1001,6 +1015,10 @@ var kindLeft := op^.left^.token.kind; if kindRight in [intconst,uintconst,longconst,ulongconst] then begin if kindLeft in [intconst,uintconst,longconst,ulongconst] then begin + if kind = preprocessorExpression then begin + kindLeft := PPKind(op^.left^.token); + kindRight := PPKind(op^.right^.token); + end; {if} {do the usual binary conversions} if (kindRight = ulongconst) or (kindLeft = ulongconst) then @@ -1287,6 +1305,8 @@ var {evaluate a constant operation} ekind := op^.left^.token.kind; + if kind = preprocessorExpression then + ekind := PPKind(op^.left^.token); op1 := IntVal(op^.left^.token); dispose(op^.left); op^.left := nil;