Correctly handle tentative struct/union and array definitions that are not completed.

In the case of structs or unions, an error is now produced. This addresses one of the problems mentioned in issue #53.

In the case of arrays, tentative definitions like "int i[];" are now permitted at file scope. If not completed by a subsequent definition, this winds up producing an array with one element, initialized to 0. See the discussion and example in C99/C11 section 6.9.2 (or C90 section 6.7.2 and example in TC1).
This commit is contained in:
Stephen Heumann 2018-03-06 22:53:52 -06:00
parent c55acd1150
commit 324c979f3b
2 changed files with 26 additions and 1 deletions

View File

@ -3592,7 +3592,8 @@ else {if not isFunction then} begin
end; {if}
{check to insure array sizes are specified}
if storageClass <> typedefsy then
CheckArray(variable, (storageClass = externsy) or doingParameters);
CheckArray(variable,
(storageClass = externsy) or doingParameters or not doingFunction);
{allocate space}
if variable^.storage = stackFrame then begin
variable^.lln := GetLocalLabel;

View File

@ -448,6 +448,7 @@ procedure DoGlobals;
size: longint; {size of the array}
sp: identPtr; {pointer to a symbol table entry}
tPtr: typePtr; {type of global array/struct/union}
msg: stringPtr; {error message ptr}
begin {GenArrays}
didOne := false;
@ -502,6 +503,26 @@ procedure DoGlobals;
end {if}
else begin
size := sp^.itype^.size;
if size = 0 then begin
if sp^.itype^.kind = arrayType then begin
{implicitly initialize with one element}
size := sp^.itype^.aType^.size;
end {if}
else begin
numErrors := numErrors+1;
new(msg);
msg^ := concat('The struct or union ''', sp^.name^,
''' has incomplete type that was never completed.');
writeln('*** ', msg^);
if terminalErrors then begin
if enterEditor then
ExitToEditor(msg, ord4(firstPtr)-ord4(bofPtr))
else
TermError(0);
end; {if}
liDCBGS.merrf := 16;
end; {else}
end; {if}
Gen2Name(dc_glb, long(size).lsw & $7FFF,
ord(sp^.storage = private), sp^.name);
size := size & $FFFF8000;
@ -567,6 +588,9 @@ procedure DoGlobals;
otherwise: Error(57);
end; {case}
end {if}
{else if sp^.itype^.size = 0 then begin
Error(57);
end {else if}
else
Gen2Name(dc_glb, ord(sp^.itype^.size),
ord(sp^.storage = private), sp^.name);