mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-09-28 10:54:30 +00:00
Fix several initialization issues.
This fixes case 1 (dealing with run-time initialization of structures containing bit-fields) and case 2 (dealing with initialization of structs where initializer values are not provided for all elements) from issue #59. It also fixes cases that could result in invalid initialization of unions if their first element was not the longest, as in the following example: #include <stdio.h> union U { int i; long l; }; int main(void) { union U a[5] = {1,2,3,4}; printf("a[0].i=%i, a[1].i=%i, a[2].i=%i, a[3].i=%i, a[4].i=%i\n", a[0].i, a[1].i, a[2].i, a[3].i, a[4].i); }
This commit is contained in:
parent
8b4213cd5a
commit
4d10fbae01
39
Parser.pas
39
Parser.pas
@ -2184,6 +2184,7 @@ var
|
|||||||
ip: identPtr; {for tracing field lists}
|
ip: identPtr; {for tracing field lists}
|
||||||
kind: typeKind; {base type of an initializer}
|
kind: typeKind; {base type of an initializer}
|
||||||
ktp: typePtr; {array type with definedTypes removed}
|
ktp: typePtr; {array type with definedTypes removed}
|
||||||
|
lPrintMacroExpansions: boolean; {local copy of printMacroExpansions}
|
||||||
|
|
||||||
|
|
||||||
procedure Fill (count: longint; tp: typePtr);
|
procedure Fill (count: longint; tp: typePtr);
|
||||||
@ -2388,10 +2389,21 @@ var
|
|||||||
count := tp^.size;
|
count := tp^.size;
|
||||||
ip := tp^.fieldList;
|
ip := tp^.fieldList;
|
||||||
bitCount := 0;
|
bitCount := 0;
|
||||||
while (ip <> nil) and (ip^.itype^.size > 0)
|
lPrintMacroExpansions := printMacroExpansions;
|
||||||
and (token.kind <> rbracech) do begin
|
while (ip <> nil) and (ip^.itype^.size > 0) do begin
|
||||||
if ip^.isForwardDeclared then
|
if ip^.isForwardDeclared then
|
||||||
ResolveForwardReference(ip);
|
ResolveForwardReference(ip);
|
||||||
|
if token.kind = rbracech then begin {initialize this field to 0}
|
||||||
|
printMacroExpansions := false; {inhibit token echo}
|
||||||
|
PutBackToken(token, false);
|
||||||
|
PutBackToken(token, false);
|
||||||
|
token.kind := intconst;
|
||||||
|
token.class := intConstant;
|
||||||
|
token.ival := 0;
|
||||||
|
PutBackToken(token, false);
|
||||||
|
token.kind := lbracech;
|
||||||
|
token.class := reservedSymbol;
|
||||||
|
end; {if}
|
||||||
if ip^.bitSize = 0 then
|
if ip^.bitSize = 0 then
|
||||||
if bitCount > 0 then begin
|
if bitCount > 0 then begin
|
||||||
InitializeBitField;
|
InitializeBitField;
|
||||||
@ -2419,7 +2431,7 @@ var
|
|||||||
if ip <> nil then
|
if ip <> nil then
|
||||||
NextToken;
|
NextToken;
|
||||||
end {if}
|
end {if}
|
||||||
else
|
else if token.kind <> rbracech then
|
||||||
ip := nil;
|
ip := nil;
|
||||||
end; {while}
|
end; {while}
|
||||||
if bitCount > 0 then begin
|
if bitCount > 0 then begin
|
||||||
@ -2429,7 +2441,9 @@ var
|
|||||||
bitCount := 0;
|
bitCount := 0;
|
||||||
end; {if}
|
end; {if}
|
||||||
if count > 0 then
|
if count > 0 then
|
||||||
|
if variable^.storage in [external,global,private] then
|
||||||
Fill(count, bytePtr);
|
Fill(count, bytePtr);
|
||||||
|
printMacroExpansions := lPrintMacroExpansions;
|
||||||
end {if}
|
end {if}
|
||||||
else {struct/union assignment initializer}
|
else {struct/union assignment initializer}
|
||||||
GetInitializerValue(tp, bitsize, bitdisp);
|
GetInitializerValue(tp, bitsize, bitdisp);
|
||||||
@ -3809,6 +3823,7 @@ var
|
|||||||
fp: identPtr; {for tracing field lists}
|
fp: identPtr; {for tracing field lists}
|
||||||
size: integer; {fill size}
|
size: integer; {fill size}
|
||||||
union: boolean; {are we doing a union?}
|
union: boolean; {are we doing a union?}
|
||||||
|
startDisp,endDisp: longint; {disp at start/end of struct/union}
|
||||||
|
|
||||||
{bit field manipulation}
|
{bit field manipulation}
|
||||||
{----------------------}
|
{----------------------}
|
||||||
@ -3966,6 +3981,8 @@ var
|
|||||||
1: end;
|
1: end;
|
||||||
|
|
||||||
structType,unionType: begin
|
structType,unionType: begin
|
||||||
|
startDisp := disp;
|
||||||
|
endDisp := disp + itype^.size;
|
||||||
if iPtr^.isStructOrUnion then begin
|
if iPtr^.isStructOrUnion then begin
|
||||||
LoadAddress; {load the destination address}
|
LoadAddress; {load the destination address}
|
||||||
GenerateCode(iptr^.iTree); {load the stuct address}
|
GenerateCode(iptr^.iTree); {load the stuct address}
|
||||||
@ -3979,18 +3996,17 @@ var
|
|||||||
else begin
|
else begin
|
||||||
union := itype^.kind = unionType;
|
union := itype^.kind = unionType;
|
||||||
fp := itype^.fieldList;
|
fp := itype^.fieldList;
|
||||||
bitsize := iPtr^.bitsize;
|
|
||||||
bitdisp := iPtr^.bitdisp;
|
|
||||||
bitcount := 0;
|
|
||||||
while fp <> nil do begin
|
while fp <> nil do begin
|
||||||
itype := fp^.itype;
|
itype := fp^.itype;
|
||||||
|
disp := startDisp + fp^.disp;
|
||||||
|
bitdisp := fp^.bitdisp;
|
||||||
|
bitsize := fp^.bitsize;
|
||||||
{ writeln('Initialize: disp = ', disp:3, '; fp^. Disp = ', fp^.disp:3, 'itype^.size = ', itype^.size:1); {debug}
|
{ writeln('Initialize: disp = ', disp:3, '; fp^. Disp = ', fp^.disp:3, 'itype^.size = ', itype^.size:1); {debug}
|
||||||
{ writeln(' bitDisp = ', bitDisp:3, '; fp^.bitDisp = ', fp^.bitDisp:3); {debug}
|
{ writeln(' bitDisp = ', bitDisp:3, '; fp^.bitDisp = ', fp^.bitDisp:3); {debug}
|
||||||
{ writeln(' bitSize = ', bitSize:3, '; fp^.bitSize = ', fp^.bitSize:3); {debug}
|
{ writeln(' bitSize = ', bitSize:3, '; fp^.bitSize = ', fp^.bitSize:3); {debug}
|
||||||
Initialize(id, disp, itype);
|
Initialize(id, disp, itype);
|
||||||
if bitsize = 0 then begin
|
if bitsize = 0 then begin
|
||||||
if bitcount <> 0 then begin
|
if bitcount <> 0 then begin
|
||||||
disp := disp + (bitcount+7) div 8;
|
|
||||||
bitcount := 0;
|
bitcount := 0;
|
||||||
end {if}
|
end {if}
|
||||||
else if fp^.bitSize <> 0 then begin
|
else if fp^.bitSize <> 0 then begin
|
||||||
@ -4005,18 +4021,12 @@ var
|
|||||||
bitcount := 0;
|
bitcount := 0;
|
||||||
end; {while}
|
end; {while}
|
||||||
bitcount := 0;
|
bitcount := 0;
|
||||||
disp := disp + 1;
|
end; {else if}
|
||||||
end {else if}
|
|
||||||
else
|
|
||||||
disp := disp + itype^.size;
|
|
||||||
end {if}
|
end {if}
|
||||||
else if fp^.bitSize = 0 then begin
|
else if fp^.bitSize = 0 then begin
|
||||||
bitsize := 0;
|
bitsize := 0;
|
||||||
disp := disp + itype^.size;
|
|
||||||
end {else if}
|
end {else if}
|
||||||
else begin
|
else begin
|
||||||
if bitsize + bitdisp < bitcount then
|
|
||||||
disp := disp + (bitcount + 7) div 8;
|
|
||||||
bitcount := bitsize + bitdisp;
|
bitcount := bitsize + bitdisp;
|
||||||
end; {else}
|
end; {else}
|
||||||
if itype^.kind in [scalarType,pointerType,enumType] then begin
|
if itype^.kind in [scalarType,pointerType,enumType] then begin
|
||||||
@ -4034,6 +4044,7 @@ var
|
|||||||
fp := fp^.next;
|
fp := fp^.next;
|
||||||
end; {while}
|
end; {while}
|
||||||
end; {else}
|
end; {else}
|
||||||
|
disp := endDisp;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
otherwise: Error(57);
|
otherwise: Error(57);
|
||||||
|
Loading…
Reference in New Issue
Block a user