Allow initializers where a string literal begins a longer expression.

This is needed to support cases like:

char s[5] = {"abc"[1]};
This commit is contained in:
Stephen Heumann 2022-11-29 21:15:42 -06:00
parent 1f468c437f
commit e7940db4c8

View File

@ -1863,6 +1863,7 @@ var
ip: identList; {used to place an id in the list} ip: identList; {used to place an id in the list}
isStatic: boolean; {static storage duration (or automatic)?} isStatic: boolean; {static storage duration (or automatic)?}
luseGlobalPool: boolean; {local copy of useGlobalPool} luseGlobalPool: boolean; {local copy of useGlobalPool}
tToken: tokenType; {temporary copy of token}
procedure InsertInitializerRecord (iPtr: initializerPtr; size: longint); procedure InsertInitializerRecord (iPtr: initializerPtr; size: longint);
@ -2329,6 +2330,7 @@ var
lSuppressMacroExpansions: boolean;{local copy of suppressMacroExpansions} lSuppressMacroExpansions: boolean;{local copy of suppressMacroExpansions}
maxDisp: longint; {maximum disp value so far} maxDisp: longint; {maximum disp value so far}
newDisp: longint; {new disp set by a designator} newDisp: longint; {new disp set by a designator}
nextTokenKind: tokenEnum; {kind of next token}
startingDisp: longint; {disp at start of this term} startingDisp: longint; {disp at start of this term}
stringElementType: typePtr; {element type of string literal} stringElementType: typePtr; {element type of string literal}
stringLength: integer; {elements in a string literal} stringLength: integer; {elements in a string literal}
@ -2464,60 +2466,68 @@ var
kind := ktp^.kind; kind := ktp^.kind;
{handle string constants} {handle string constants}
if token.kind = stringConst then if (token.kind = stringConst) and (kind = scalarType) then begin
stringElementType := StringType(token.prefix)^.aType; stringElementType := StringType(token.prefix)^.aType;
if (token.kind = stringConst) and (kind = scalarType) and if ((ktp^.baseType in [cgByte,cgUByte]) and (stringElementType^.size=1))
(((ktp^.baseType in [cgByte,cgUByte]) or CompTypes(ktp,stringElementType) then begin
and (stringElementType = charPtr)) tToken := token;
or CompTypes(ktp,stringElementType)) then begin NextToken;
stringLength := token.sval^.length div ord(stringElementType^.size); nextTokenKind := token.kind;
if tp^.elements = 0 then begin PutBackToken(token, false, true);
tp^.elements := stringLength; token := tToken;
RecomputeSizes(variable^.itype); if nextTokenKind in [commach, rbracech, semicolonch] then begin
end {if} stringLength :=
else if tp^.elements < stringLength-1 then begin token.sval^.length div ord(stringElementType^.size);
Error(44); if tp^.elements = 0 then begin
errorFound := true; tp^.elements := stringLength;
end; {else if} RecomputeSizes(variable^.itype);
with ktp^ do begin end {if}
iPtr := pointer(Malloc(sizeof(initializerRecord))); else if tp^.elements < stringLength-1 then begin
iPtr^.count := 1; Error(44);
iPtr^.bitdisp := 0; errorFound := true;
iPtr^.bitsize := 0;
if isStatic then begin
InsertInitializerRecord(iPtr, token.sval^.length);
iPtr^.isConstant := true;
iPtr^.basetype := cgString;
iPtr^.sval := token.sval;
count := tp^.elements - stringLength;
if count > 0 then
Fill(count, stringElementType)
else if count = -1 then begin
iPtr^.sval := pointer(GMalloc(token.sval^.length+2));
CopyLongString(iPtr^.sval, token.sval);
iPtr^.sval^.length :=
iPtr^.sval^.length - ord(stringElementType^.size);
end; {else if} end; {else if}
end {if} with ktp^ do begin
else begin iPtr := pointer(Malloc(sizeof(initializerRecord)));
InsertInitializerRecord(iPtr, iPtr^.count := 1;
tp^.elements * stringElementType^.size); iPtr^.bitdisp := 0;
iPtr^.isConstant := false; iPtr^.bitsize := 0;
new(ep); if isStatic then begin
iPtr^.iTree := ep; InsertInitializerRecord(iPtr, token.sval^.length);
iPtr^.iType := tp; iPtr^.isConstant := true;
ep^.next := nil; iPtr^.basetype := cgString;
ep^.left := nil; iPtr^.sval := token.sval;
ep^.middle := nil; count := tp^.elements - stringLength;
ep^.right := nil; if count > 0 then
ep^.token := token; Fill(count, stringElementType)
end; {else} else if count = -1 then begin
end; {with} iPtr^.sval := pointer(GMalloc(token.sval^.length+2));
NextToken; CopyLongString(iPtr^.sval, token.sval);
end {if} iPtr^.sval^.length :=
iPtr^.sval^.length - ord(stringElementType^.size);
end; {else if}
end {if}
else begin
InsertInitializerRecord(iPtr,
tp^.elements * stringElementType^.size);
iPtr^.isConstant := false;
new(ep);
iPtr^.iTree := ep;
iPtr^.iType := tp;
ep^.next := nil;
ep^.left := nil;
ep^.middle := nil;
ep^.right := nil;
ep^.token := token;
end; {else}
end; {with}
NextToken;
goto 1;
end; {if}
end; {if}
end; {if}
{handle arrays not initialized with a string constant} {handle arrays not initialized with a string constant}
else if kind in if kind in
[scalarType,pointerType,enumType,arrayType,structType,unionType] then [scalarType,pointerType,enumType,arrayType,structType,unionType] then
begin begin
count := 0; {get the expressions|initializers} count := 0; {get the expressions|initializers}
@ -2749,7 +2759,7 @@ var
Error(47); Error(47);
errorFound := true; errorFound := true;
end; {else} end; {else}
1:
if braces then begin {if there was an opening brace then } if braces then begin {if there was an opening brace then }
if token.kind = commach then { insist on a closing brace } if token.kind = commach then { insist on a closing brace }
NextToken; NextToken;
@ -2763,7 +2773,6 @@ var
errorFound := true; errorFound := true;
end; {else} end; {else}
end; {if} end; {if}
1:
end; {InitializeTerm} end; {InitializeTerm}
begin {Initializer} begin {Initializer}