From b4604e079ec2102b6eee1e4c0401b06b534e6c93 Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 16 Feb 2021 23:45:59 -0600 Subject: [PATCH] Do preprocessor arithmetic in intmax_t/uintmax_t (aka long long types). This is what C99 and later require. --- Expression.pas | 32 +++++++++++++++----------------- Scanner.pas | 20 +++++++++++++++++--- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/Expression.pas b/Expression.pas index 6eefc63..9990f37 100644 --- a/Expression.pas +++ b/Expression.pas @@ -929,7 +929,7 @@ var { do an operation } - label 1; + label 1,2; var baseType: baseTypeEnum; {base type of value to cast} @@ -1047,10 +1047,10 @@ var { 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 + if token.kind in [intconst,longconst] then + PPKind := longlongconst + else if token.kind in [uintconst,ulongconst] then + PPKind := ulonglongconst else PPKind := token.kind; end; {PPKind} @@ -1133,10 +1133,8 @@ 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} + if kind = preprocessorExpression then + goto 2; {do the usual binary conversions} if (kindRight = ulongconst) or (kindLeft = ulongconst) then @@ -1269,7 +1267,7 @@ var goto 1; end; {if} end; {if} - +2: if kindRight in [intconst,uintconst,longconst,ulongconst, longlongconst,ulonglongconst] then begin if kindLeft in [intconst,uintconst,longconst,ulongconst, @@ -1610,13 +1608,11 @@ var else if not (op^.token.kind in [typedef,plusplusop,minusminusop,opplusplus,opminusminus,uand]) then begin - if (op^.left^.token.kind + if (kind <> preprocessorExpression) and (op^.left^.token.kind in [intconst,uintconst,longconst,ulongconst]) then begin {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; @@ -1640,12 +1636,14 @@ var op^.token.ival := long(op1).lsw; end; {else} end {if} - else if op^.left^.token.kind - in [longlongconst,ulonglongconst] then begin + else if op^.left^.token.kind in [longlongconst,ulonglongconst, + intconst,uintconst,longconst,ulongconst] then begin - {evaluate a constant operation} + {evaluate a constant operation with long long operand} ekind := op^.left^.token.kind; - llop1 := op^.left^.token.qval; + if kind = preprocessorExpression then + ekind := PPKind(op^.left^.token); + GetLongLongVal(llop1, op^.left^.token); dispose(op^.left); op^.left := nil; case op^.token.kind of diff --git a/Scanner.pas b/Scanner.pas index 8b3ebdb..f4ba67e 100644 --- a/Scanner.pas +++ b/Scanner.pas @@ -2845,6 +2845,9 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin { 16 - check for stack errors } FlagPragmas(p_debug); NumericDirective; + if expressionType^.kind = scalarType then + if expressionType^.baseType in [cgQuad,cgUQuad] then + expressionValue := llExpressionValue.lo; val := long(expressionValue).lsw; rangeCheck := odd(val); debugFlag := odd(val >> 1); @@ -2859,7 +2862,10 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin end {else} else if token.name^ = 'lint' then begin FlagPragmas(p_lint); - NumericDirective; + NumericDirective; + if expressionType^.kind = scalarType then + if expressionType^.baseType in [cgQuad,cgUQuad] then + expressionValue := llExpressionValue.lo; lint := long(expressionValue).lsw; lintIsError := true; if token.kind = semicolonch then begin @@ -2893,7 +2899,10 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin { 16 - common subexpression elimination } { 32 - loop invariant removal } FlagPragmas(p_optimize); - NumericDirective; + NumericDirective; + if expressionType^.kind = scalarType then + if expressionType^.baseType in [cgQuad,cgUQuad] then + expressionValue := llExpressionValue.lo; val := long(expressionValue).lsw; peepHole := odd(val); npeepHole := odd(val >> 1); @@ -2990,7 +2999,10 @@ if ch in ['a','d','e','i','l','p','u','w'] then begin { 8 - allow // comments } { 16 - allow mixed decls & use C99 scope rules } FlagPragmas(p_ignore); - NumericDirective; + NumericDirective; + if expressionType^.kind = scalarType then + if expressionType^.baseType in [cgQuad,cgUQuad] then + expressionValue := llExpressionValue.lo; val := long(expressionValue).lsw; skipIllegalTokens := odd(val); allowLongIntChar := odd(val >> 1); @@ -3342,6 +3354,8 @@ if c2 in ['f','F'] then begin {allow F designator on reals} NextChar; end; {if} numString[0] := chr(stringIndex); {set the length of the string} +if doingPPExpression then + isLongLong := true; if isReal then begin {convert a real constant} token.kind := doubleConst; token.class := doubleConstant;