From 324c979f3bd72bd5544f3af1f0ff2945b963717f Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Tue, 6 Mar 2018 22:53:52 -0600 Subject: [PATCH] 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). --- Parser.pas | 3 ++- Symbol.pas | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/Parser.pas b/Parser.pas index bbb7346..cef91ef 100644 --- a/Parser.pas +++ b/Parser.pas @@ -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; diff --git a/Symbol.pas b/Symbol.pas index a36796b..4ea789f 100644 --- a/Symbol.pas +++ b/Symbol.pas @@ -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);