Prevent struct/union members from having incomplete type, except for flexible array member.

ORCA/C previously allowed struct/union members to be declared with incomplete type. Because of this, it allowed C99-style flexible array members to be declared, albeit by accident rather than by design. In some basic testing, these seem to work correctly, except that they could be initialized and that would give rise to odd behavior.

I have restricted it to allowing flexible array members only in the cases allowed by C99/C11, and otherwise disallowing members with incomplete type. I have also prohibited initializing flexible array members.
This commit is contained in:
Stephen Heumann 2016-10-16 22:56:34 -05:00
parent 972b0109a4
commit 45cc0a0721
2 changed files with 14 additions and 1 deletions

View File

@ -2298,7 +2298,8 @@ var
count := tp^.size;
ip := tp^.fieldList;
bitCount := 0;
while (ip <> nil) and (token.kind <> rbracech) do begin
while (ip <> nil) and (ip^.itype^.size > 0)
and (token.kind <> rbracech) do begin
if ip^.isForwardDeclared then
ResolveForwardReference(ip);
InitializeTerm(ip^.itype, ip^.bitsize, ip^.bitdisp, false);
@ -2449,6 +2450,7 @@ var
lstorageClass: tokenEnum; {storage class of the declaration}
maxDisp: longint; {for determining union sizes}
variable: identPtr; {variable being defined}
didFlexibleArray: boolean; {have we seen a flexible array member?}
begin {FieldList}
ldoingParameters := doingParameters; {allow fields in K&R dec. area}
@ -2459,6 +2461,7 @@ var
bitDisp := 0; {start allocation from byte 0}
disp := 0;
maxDisp := 0;
didFlexibleArray := false;
fl := nil; {nothing in the field list, yet}
{check for no declarations}
if not (token.kind in [unsignedsy,signedsy,intsy,longsy,charsy,shortsy,
@ -2473,6 +2476,8 @@ var
TypeSpecifier(true,false); {get the type specifier}
if not skipDeclarator then
repeat {declare the variables...}
if didFlexibleArray then
Error(118);
variable := nil;
if token.kind <> colonch then begin
Declarator(typeSpec, variable, fieldListSpace, false);
@ -2535,6 +2540,12 @@ var
disp := disp + variable^.itype^.size;
if disp > maxDisp then
maxDisp := disp;
if variable^.itype^.size = 0 then
if (variable^.itype^.kind = arrayType)
and (disp > 0) then {handle flexible array member}
didFlexibleArray := true
else
Error(117);
end {if}
else
Error(116);

View File

@ -597,6 +597,8 @@ if list or (numErr <> 0) then begin
114: msg := @'a function call was made to a non-function';
115: msg := @'illegal bit field declaration';
116: msg := @'missing field name';
117: msg := @'field cannot have incomplete type';
118: msg := @'flexible array must be last member of structure';
otherwise: Error(57);
end; {case}
writeln(msg^);