Use the right types for constants cast to character types.

These were previously treated as having type int. This resulted in incorrect results from sizeof, and would also be a problem for _Generic if it was implemented.

Note that this creates a token kind of "charconst", but this is not the kind for character constants in the source code. Those have type int, so their kind is intconst. The new kinds of "tokens" are created only through casts of constant expressions.
This commit is contained in:
Stephen Heumann 2021-03-07 13:38:21 -06:00
parent 8f8e7f12e2
commit 979852be3c
6 changed files with 83 additions and 33 deletions

View File

@ -167,9 +167,12 @@ type
tokenEnum = ( {enumeration of the tokens} tokenEnum = ( {enumeration of the tokens}
ident, {identifiers} ident, {identifiers}
{constants} {constants}
{Note: compconst and charconst, etc. }
{ are not found in program code. }
{ They are created only by casts. }
intconst,uintconst,longconst,ulongconst,longlongconst, intconst,uintconst,longconst,ulongconst,longlongconst,
ulonglongconst,floatconst,doubleconst,extendedconst,compconst, ulonglongconst,floatconst,doubleconst,extendedconst,compconst,
stringconst, charconst,scharconst,ucharconst,stringconst,
{reserved words} {reserved words}
_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy, _Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy,
_Genericsy,_Imaginarysy,_Noreturnsy,_Static_assertsy,_Thread_localsy, _Genericsy,_Imaginarysy,_Noreturnsy,_Static_assertsy,_Thread_localsy,

View File

@ -1026,7 +1026,7 @@ var
{ convert an operand to a real value } { convert an operand to a real value }
begin {RealVal} begin {RealVal}
if token.kind = intconst then if token.kind in [intconst,charconst,scharconst,ucharconst] then
RealVal := token.ival RealVal := token.ival
else if token.kind = uintconst then begin else if token.kind = uintconst then begin
if token.ival < 0 then if token.ival < 0 then
@ -1056,7 +1056,7 @@ var
{ convert an operand to a longint value } { convert an operand to a longint value }
begin {IntVal} begin {IntVal}
if token.kind = intconst then if token.kind in [intconst,charconst,scharconst,ucharconst] then
IntVal := token.ival IntVal := token.ival
else if token.kind = uintconst then begin else if token.kind = uintconst then begin
IntVal := token.ival & $0000FFFF; IntVal := token.ival & $0000FFFF;
@ -1072,7 +1072,7 @@ var
{ convert an operand to a long long value } { convert an operand to a long long value }
begin {LongLongVal} begin {LongLongVal}
if token.kind = intconst then begin if token.kind in [intconst,charconst,scharconst,ucharconst] then begin
result.lo := token.ival; result.lo := token.ival;
if result.lo < 0 then if result.lo < 0 then
result.hi := -1 result.hi := -1
@ -1144,11 +1144,14 @@ var
op^.middle := Pop; op^.middle := Pop;
op^.left := Pop; op^.left := Pop;
if op^.right^.token.kind in [intconst,uintconst, if op^.right^.token.kind in [intconst,uintconst,
longconst,ulongconst,longlongconst,ulonglongconst] then longconst,ulongconst,longlongconst,ulonglongconst,
charconst,scharconst,ucharconst] then
if op^.left^.token.kind in [intconst,uintconst, if op^.left^.token.kind in [intconst,uintconst,
longconst,ulongconst,longlongconst,ulonglongconst] then longconst,ulongconst,longlongconst,ulonglongconst,
charconst,scharconst,ucharconst] then
if op^.middle^.token.kind in [intconst,uintconst, if op^.middle^.token.kind in [intconst,uintconst,
longconst,ulongconst,longlongconst,ulonglongconst] then begin longconst,ulongconst,longlongconst,ulonglongconst,
charconst,scharconst,ucharconst] then begin
GetLongLongVal(llop1, op^.left^.token); GetLongLongVal(llop1, op^.left^.token);
if (llop1.lo <> 0) or (llop1.hi <> 0) then if (llop1.lo <> 0) or (llop1.hi <> 0) then
op^.token := op^.middle^.token op^.token := op^.middle^.token
@ -1190,8 +1193,10 @@ var
op^.left := Pop; op^.left := Pop;
kindRight := op^.right^.token.kind; kindRight := op^.right^.token.kind;
kindLeft := op^.left^.token.kind; kindLeft := op^.left^.token.kind;
if kindRight in [intconst,uintconst,longconst,ulongconst] then begin if kindRight in [intconst,uintconst,longconst,ulongconst,
if kindLeft in [intconst,uintconst,longconst,ulongconst] then begin charconst,scharconst,ucharconst] then begin
if kindLeft in [intconst,uintconst,longconst,ulongconst,
charconst,scharconst,ucharconst] then begin
if kind = preprocessorExpression then if kind = preprocessorExpression then
goto 2; goto 2;
@ -1328,9 +1333,11 @@ var
end; {if} end; {if}
2: 2:
if kindRight in [intconst,uintconst,longconst,ulongconst, if kindRight in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst] then begin longlongconst,ulonglongconst,charconst,scharconst,ucharconst]
then begin
if kindLeft in [intconst,uintconst,longconst,ulongconst, if kindLeft in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst] then begin longlongconst,ulonglongconst,charconst,scharconst,ucharconst]
then begin
if kind = preprocessorExpression then begin if kind = preprocessorExpression then begin
kindLeft := PPKind(op^.left^.token); kindLeft := PPKind(op^.left^.token);
@ -1478,10 +1485,10 @@ var
if op^.right^.token.kind in [intconst,uintconst,longconst,ulongconst, if op^.right^.token.kind in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst,floatconst,doubleconst,extendedconst, longlongconst,ulonglongconst,floatconst,doubleconst,extendedconst,
compconst] then compconst,charconst,scharconst,ucharconst] then
if op^.left^.token.kind in [intconst,uintconst,longconst,ulongconst, if op^.left^.token.kind in [intconst,uintconst,longconst,ulongconst,
longlongconst,ulonglongconst,floatconst,doubleconst,extendedconst, longlongconst,ulonglongconst,floatconst,doubleconst,extendedconst,
compconst] then compconst,charconst,scharconst,ucharconst] then
begin begin
if fenvAccess then if fenvAccess then
if kind in [normalExpression, autoInitializerExpression] then if kind in [normalExpression, autoInitializerExpression] then
@ -1632,7 +1639,10 @@ var
dispose(op^.left); dispose(op^.left);
op^.left := nil; op^.left := nil;
if baseType in [cgByte,cgWord] then begin if baseType in [cgByte,cgWord] then begin
op^.token.kind := intConst; if baseType = cgByte then
op^.token.kind := scharConst
else
op^.token.kind := intConst;
op^.token.class := intConstant; op^.token.class := intConstant;
if tp^.cType = ctBool then if tp^.cType = ctBool then
op^.token.ival := ord(rop1 <> 0.0) op^.token.ival := ord(rop1 <> 0.0)
@ -1651,7 +1661,10 @@ var
op^.token.ival := long(llop1.lo).lsw; op^.token.ival := long(llop1.lo).lsw;
end {else if} end {else if}
else if baseType = cgUByte then begin else if baseType = cgUByte then begin
op^.token.kind := intConst; if tp^.cType = ctUChar then
op^.token.kind := ucharConst
else
op^.token.kind := charConst;
op^.token.class := intConstant; op^.token.class := intConstant;
op^.token.ival := long(llop1.lo).lsw; op^.token.ival := long(llop1.lo).lsw;
op^.token.ival := op^.token.ival & $00FF; op^.token.ival := op^.token.ival & $00FF;
@ -1696,10 +1709,13 @@ var
[typedef,plusplusop,minusminusop,opplusplus,opminusminus,uand]) then [typedef,plusplusop,minusminusop,opplusplus,opminusminus,uand]) then
begin begin
if (kind <> preprocessorExpression) and (op^.left^.token.kind if (kind <> preprocessorExpression) and (op^.left^.token.kind
in [intconst,uintconst,longconst,ulongconst]) then begin in [intconst,uintconst,longconst,ulongconst,charconst,scharconst,
ucharconst]) then begin
{evaluate a constant operation} {evaluate a constant operation}
ekind := op^.left^.token.kind; ekind := op^.left^.token.kind;
if ekind in [charconst,scharconst,ucharconst] then
ekind := intconst;
op1 := IntVal(op^.left^.token); op1 := IntVal(op^.left^.token);
dispose(op^.left); dispose(op^.left);
op^.left := nil; op^.left := nil;
@ -1724,10 +1740,13 @@ var
end; {else} end; {else}
end {if} end {if}
else if op^.left^.token.kind in [longlongconst,ulonglongconst, else if op^.left^.token.kind in [longlongconst,ulonglongconst,
intconst,uintconst,longconst,ulongconst] then begin intconst,uintconst,longconst,ulongconst,charconst,scharconst,
ucharconst] then begin
{evaluate a constant operation with long long operand} {evaluate a constant operation with long long operand}
ekind := op^.left^.token.kind; ekind := op^.left^.token.kind;
if ekind in [charconst,scharconst,ucharconst] then
ekind := intconst;
if kind = preprocessorExpression then if kind = preprocessorExpression then
ekind := PPKind(op^.left^.token); ekind := PPKind(op^.left^.token);
GetLongLongVal(llop1, op^.left^.token); GetLongLongVal(llop1, op^.left^.token);
@ -3279,15 +3298,21 @@ case tree^.token.kind of
end; {case} end; {case}
end; end;
intConst,uintConst: begin intConst,uintConst,charConst,scharConst,ucharConst: begin
Gen1t(pc_ldc, tree^.token.ival, cgWord); Gen1t(pc_ldc, tree^.token.ival, cgWord);
lastwasconst := true; lastwasconst := true;
lastconst := tree^.token.ival; lastconst := tree^.token.ival;
if tree^.token.kind = intConst then if tree^.token.kind = intConst then
expressionType := intPtr expressionType := intPtr
else else if tree^.token.kind = uintConst then
expressionType := uIntPtr; expressionType := uIntPtr
end; {case intConst} else if tree^.token.kind = charConst then
expressionType := charPtr
else if tree^.token.kind = scharConst then
expressionType := scharPtr
else {if tree^.token.kind = ucharConst then}
expressionType := ucharPtr;
end; {case intConst,uintConst,charConst,scharConst,ucharConst}
longConst,ulongConst: begin longConst,ulongConst: begin
GenLdcLong(tree^.token.lval); GenLdcLong(tree^.token.lval);
@ -4391,7 +4416,8 @@ else begin {record the expression for an initialize
castValue := tree^.left; castValue := tree^.left;
while castValue^.token.kind = castoper do while castValue^.token.kind = castoper do
castValue := castValue^.left; castValue := castValue^.left;
if castValue^.token.kind in [intconst,uintconst] then begin if castValue^.token.kind in
[intconst,uintconst,charconst,scharconst,ucharconst] then begin
expressionValue := castValue^.token.ival; expressionValue := castValue^.token.ival;
isConstant := true; isConstant := true;
expressionType := tree^.castType; expressionType := tree^.castType;
@ -4407,9 +4433,17 @@ else begin {record the expression for an initialize
goto 1; goto 1;
end; {if} end; {if}
end; {if} end; {if}
if tree^.token.kind = intconst then begin if tree^.token.kind in [intconst,charconst,scharconst,ucharconst] then
begin
expressionValue := tree^.token.ival; expressionValue := tree^.token.ival;
expressionType := intPtr; if tree^.token.kind = intconst then
expressionType := intPtr
else if tree^.token.kind = charconst then
expressionType := charPtr
else if tree^.token.kind = scharconst then
expressionType := scharPtr
else {if tree^.token.kind = ucharconst then}
expressionType := ucharPtr;
isConstant := true; isConstant := true;
end {else if} end {else if}
else if tree^.token.kind = uintconst then begin else if tree^.token.kind = uintconst then begin
@ -4515,7 +4549,7 @@ procedure InitExpression;
begin {InitExpression} begin {InitExpression}
startTerm := [ident,intconst,uintconst,longconst,ulongconst,longlongconst, startTerm := [ident,intconst,uintconst,longconst,ulongconst,longlongconst,
ulonglongconst,floatconst,doubleconst,extendedconst,compconst, ulonglongconst,floatconst,doubleconst,extendedconst,compconst,
stringconst,_Genericsy]; charconst,scharconst,ucharconst,stringconst,_Genericsy];
startExpression:= startTerm + startExpression:= startTerm +
[lparench,asteriskch,andch,plusch,minusch,excch,tildech,sizeofsy, [lparench,asteriskch,andch,plusch,minusch,excch,tildech,sizeofsy,
plusplusop,minusminusop,typedef,_Alignofsy]; plusplusop,minusminusop,typedef,_Alignofsy];

View File

@ -18,7 +18,7 @@ uses CCommon, MM, Scanner, Symbol, CGI;
{$segment 'SCANNER'} {$segment 'SCANNER'}
const const
symFileVersion = 13; {version number of .sym file format} symFileVersion = 14; {version number of .sym file format}
var var
inhibitHeader: boolean; {should .sym includes be blocked?} inhibitHeader: boolean; {should .sym includes be blocked?}

View File

@ -1891,7 +1891,8 @@ var
tree := tree^.left; tree := tree^.left;
if tree^.token.kind = plusch then begin if tree^.token.kind = plusch then begin
rtree := tree^.right; rtree := tree^.right;
if rtree^.token.kind in [intconst,uintconst] then if rtree^.token.kind in
[intconst,uintconst,charconst,scharconst,ucharconst] then
size := rtree^.token.ival size := rtree^.token.ival
else if rtree^.token.kind in [longconst,ulongconst] then else if rtree^.token.kind in [longconst,ulongconst] then
size := rtree^.token.lval size := rtree^.token.lval
@ -2134,8 +2135,9 @@ var
while operator in [plusch,minusch] do begin while operator in [plusch,minusch] do begin
with tree^.right^.token do with tree^.right^.token do
if kind in [intConst,uintconst,longConst,ulongconst, if kind in [intConst,uintconst,longConst,ulongconst,
longlongConst,ulonglongconst] then begin longlongConst,ulonglongconst,charconst,scharconst,
if kind = intConst then ucharconst] then begin
if kind in [intConst,charconst,scharconst,ucharconst] then
offSet2 := ival offSet2 := ival
else if kind = uintConst then else if kind = uintConst then
offset2 := ival & $0000ffff offset2 := ival & $0000ffff
@ -3611,7 +3613,8 @@ if isFunction then begin
with fnType^ do begin with fnType^ do begin
NextToken; NextToken;
Match(lparench,13); Match(lparench,13);
if token.kind in [intconst,uintconst] then begin if token.kind in
[intconst,uintconst,charconst,scharconst,ucharconst] then begin
toolNum := token.ival; toolNum := token.ival;
NextToken; NextToken;
end {if} end {if}
@ -3622,7 +3625,8 @@ if isFunction then begin
dispatcher := token.lval; dispatcher := token.lval;
NextToken; NextToken;
end {if} end {if}
else if token.kind in [intconst,uintconst] then begin else if token.kind in
[intconst,uintconst,charconst,scharconst,ucharconst] then begin
dispatcher := token.ival; dispatcher := token.ival;
NextToken; NextToken;
end {if} end {if}

View File

@ -747,6 +747,9 @@ case token.kind of
typedef, typedef,
ident: write(token.name^); ident: write(token.name^);
charconst,
scharconst,
ucharconst,
intconst, intconst,
uintconst: write(token.ival:1); uintconst: write(token.ival:1);

View File

@ -286,7 +286,7 @@ charSym start single character symbols
! constants ! constants
enum (intconst,uintconst,longconst,ulongconst,longlongconst) enum (intconst,uintconst,longconst,ulongconst,longlongconst)
enum (ulonglongconst,floatconst,doubleconst,extendedconst,compconst) enum (ulonglongconst,floatconst,doubleconst,extendedconst,compconst)
enum stringconst enum (charconst,scharconst,ucharconst,stringconst)
! reserved words ! reserved words
enum (_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy) enum (_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy)
enum (_Genericsy,_Imaginarysy,_Noreturnsy,_Static_assertsy,_Thread_localsy) enum (_Genericsy,_Imaginarysy,_Noreturnsy,_Static_assertsy,_Thread_localsy)
@ -363,6 +363,9 @@ icp start in-coming priority for expression
dc i1'200' doubleconst dc i1'200' doubleconst
dc i1'200' extendedconst dc i1'200' extendedconst
dc i1'200' compconst dc i1'200' compconst
dc i1'200' charconst
dc i1'200' scharconst
dc i1'200' ucharconst
dc i1'200' stringconst dc i1'200' stringconst
dc i1'200' _Alignassy dc i1'200' _Alignassy
dc i1'16' _Alignofsy dc i1'16' _Alignofsy
@ -533,6 +536,9 @@ isp start in stack priority for expression
dc i1'0' doubleconst dc i1'0' doubleconst
dc i1'0' extendedconst dc i1'0' extendedconst
dc i1'0' compconst dc i1'0' compconst
dc i1'0' charconst
dc i1'0' scharconst
dc i1'0' ucharconst
dc i1'0' stringconst dc i1'0' stringconst
dc i1'0' _Alignassy dc i1'0' _Alignassy
dc i1'16' _Alignofsy dc i1'16' _Alignofsy
@ -906,7 +912,7 @@ wordHash start reserved word hash table
! constants ! constants
enum (intconst,uintconst,longconst,ulongconst,longlongconst) enum (intconst,uintconst,longconst,ulongconst,longlongconst)
enum (ulonglongconst,floatconst,doubleconst,extendedconst,compconst) enum (ulonglongconst,floatconst,doubleconst,extendedconst,compconst)
enum stringconst enum (charconst,scharconst,ucharconst,stringconst)
! reserved words ! reserved words
enum (_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy) enum (_Alignassy,_Alignofsy,_Atomicsy,_Boolsy,_Complexsy)
enum (_Genericsy,_Imaginarysy,_Noreturnsy,_Static_assertsy,_Thread_localsy) enum (_Genericsy,_Imaginarysy,_Noreturnsy,_Static_assertsy,_Thread_localsy)