Evaluate constant expressions with long long and floating operands.

Note that we currently defer evaluation of such expressions to run time if the long long value cannot be represented exactly in a double, because statically-evaluated floating point expressions use the double format rather than the extended (long double) format used at run time.
This commit is contained in:
Stephen Heumann 2021-02-21 18:43:53 -06:00
parent b0a61fbadf
commit 4020098dd6
2 changed files with 21 additions and 17 deletions

View File

@ -983,7 +983,7 @@ var
end; {Pop}
function RealVal (token: tokenType): double;
function RealVal (token: tokenType): extended;
{ convert an operand to a real value }
@ -1004,6 +1004,10 @@ var
else
RealVal := token.lval;
end {else if}
else if token.kind = longlongconst then
RealVal := CnvLLX(token.qval)
else if token.kind = ulonglongconst then
RealVal := CnvULLX(token.qval)
else
RealVal := token.rval;
end; {RealVal}
@ -1434,14 +1438,24 @@ var
end; {if}
end; {if}
if op^.right^.token.kind in
[intconst,uintconst,longconst,ulongconst,doubleconst] then
if op^.left^.token.kind in
[intconst,uintconst,longconst,ulongconst,doubleconst] then
if op^.right^.token.kind in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst,doubleconst] then
if op^.left^.token.kind in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst,doubleconst] then
begin
ekind := doubleconst; {evaluate a constant operation}
rop1 := RealVal(op^.left^.token);
rop2 := RealVal(op^.right^.token);
extop1 := RealVal(op^.left^.token);
rop1 := extop1;
if op^.left^.token.kind in [longlongconst,ulonglongconst] then
if rop1 <> extop1 then
if not (op^.token.kind in [barbarop,andandop]) then
goto 1;
extop1 := RealVal(op^.right^.token);
rop2 := extop1;
if op^.right^.token.kind in [longlongconst,ulonglongconst] then
if rop2 <> extop1 then
if not (op^.token.kind in [barbarop,andandop]) then
goto 1;
dispose(op^.right);
op^.right := nil;
dispose(op^.left);
@ -1496,16 +1510,7 @@ var
op^.token.class := doubleConstant;
op^.token.kind := doubleConst;
end; {else}
goto 1;
end; {if}
if op^.right^.token.kind in [intconst,uintconst,longconst,
ulongconst,longlongconst,ulonglongconst,doubleconst] then
if op^.left^.token.kind in [intconst,uintconst,longconst,
ulongconst,longlongconst,ulonglongconst,doubleconst] then
if not (kind in [normalExpression,autoInitializerExpression])
then
Error(157);
1:
end;

View File

@ -692,7 +692,6 @@ if list or (numErr <> 0) then begin
154: msg := @'lint: function declared _Noreturn can return or has unreachable code';
155: msg := @'lint: non-void function may not return a value or has unreachable code';
156: msg := @'invalid suffix on numeric constant';
157: msg := @'ORCA/C cannot evaluate this constant expression with long long operand(s)';
otherwise: Error(57);
end; {case}
writeln(msg^);