Fix issues with type conversions in static initialization.

*Initialization of floating-point variables from unsigned long expressions with value > LONG_MAX would give the wrong value.
*Initialization of floating-point variables from (unsigned) long long expressions would give the wrong value.
*Initialization of _Bool variables should give 0 or 1, as per the usual rules for conversion to _Bool.
*Initialization of integer variables from floating-point expressions should be allowed, applying the usual conversions.
This commit is contained in:
Stephen Heumann 2022-12-04 16:36:16 -06:00
parent 36c70f9107
commit 736e7575cf
3 changed files with 47 additions and 3 deletions

View File

@ -220,6 +220,16 @@ function slt64(a,b: longlong): boolean; extern;
function sgt64(a,b: longlong): boolean; extern;
{-- External conversion functions; imported from CGC.pas -------}
procedure CnvXLL (var result: longlong; val: extended); extern;
procedure CnvXULL (var result: longlong; val: extended); extern;
function CnvLLX (val: longlong): extended; extern;
function CnvULLX (val: longlong): extended; extern;
{-- Parser Utility Procedures ----------------------------------}
procedure Match {kind: tokenEnum; err: integer};
@ -2073,16 +2083,36 @@ var
iPtr^.qVal.hi := -1
else
iPtr^.qVal.hi := 0;
if tp^.cType = ctBool then
iPtr^.iVal := ord(expressionValue <> 0);
goto 2;
end; {if}
if bKind in [cgReal,cgDouble,cgComp,cgExtended] then begin
if etype^.baseType in [cgByte..cgULong] then
iPtr^.rVal := expressionValue
if etype^.baseType in [cgByte..cgULong] then begin
iPtr^.rVal := expressionValue;
if etype^.baseType = cgULong then
if expressionValue < 0 then
iPtr^.rVal := iPtr^.rVal + 4294967296.0;
end {if}
else if etype^.baseType in
[cgReal,cgDouble,cgComp,cgExtended] then
iPtr^.rval := realExpressionValue;
iPtr^.rval := realExpressionValue
else if eType^.baseType = cgQuad then
iPtr^.rVal := CnvLLX(llExpressionValue)
else if eType^.baseType = cgUQuad then
iPtr^.rVal := CnvULLX(llExpressionValue);
goto 2;
end; {if}
if (etype^.baseType in [cgReal,cgDouble,cgComp,cgExtended])
and (bKind in [cgByte..cgULong,cgQuad,cgUQuad]) then begin
if tp^.cType = ctBool then
iPtr^.iVal := ord(realExpressionValue <> 0)
else if bKind = cgUQuad then
CnvXULL(iPtr^.qVal, realExpressionValue)
else
CnvXLL(iPtr^.qVal, realExpressionValue);
goto 2;
end;
Error(47);
errorFound := true;
end;

View File

@ -85,6 +85,16 @@ int main(void) {
if (s.a || !s.b)
goto Fail;
_Bool b1 = 123;
_Bool b2 = -123.5;
_Bool b3 = 0.0;
static _Bool b4 = 0x100000000;
static _Bool b5 = 0.0001;
static _Bool b6 = -0.0;
if (b1 != 1 || b2 != 1 || b3 != 0 || b4 != 1 || b5 != 1 || b6 != 0)
goto Fail;
printf ("Passed Conformance Test c99bool\n");
return 0;

View File

@ -2009,6 +2009,10 @@ int foo(int[42]);
221. Structures with unnamed bit-fields were sometimes initialized incorrectly.
222. If an expression of type unsigned long and value greater than LONG_MAX was used in the initializer for a floating-point variable with static storage duration, the wrong value would be produced.
223. Expressions of floating-point type could not be used in initializers for integer variables with static storage duration. This should be allowed, with a conversion performed as in the case of assignment.
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.