Give an error for expressions with incomplete struct/union types.

These are erroneous, in situations where the expression is used for its value. For function return types, this violates a constraint (C17 6.5.2.2 p1), so a diagnostic is required. We also now diagnose this issue for identifier expressions or unary * (indirection) expressions. These cases cause undefined behavior per C17 6.3.2.1 p2, so a diagnostic is not required, but it is nice to give one.
This commit is contained in:
Stephen Heumann 2023-01-09 21:58:05 -06:00
parent 61a2cd1e5e
commit 03fc7a43b9
2 changed files with 23 additions and 1 deletions

View File

@ -2887,6 +2887,23 @@ var
ldoDispose: boolean; {local copy of doDispose}
procedure CheckForIncompleteStructType;
{ Check if expressionType is an incomplete struct/union type. }
var
tp: typePtr; {the type}
begin
tp := expressionType;
while tp^.kind = definedType do
tp := tp^.dType;
if tp^.kind in [structType,unionType] then
if tp^.size = 0 then
Error(187);
end;
function ExpressionKind (tree: tokenPtr): typeKind;
{ returns the type of an expression }
@ -3516,6 +3533,7 @@ var
ftype^.dispatcher);
expressionType := ftype^.fType;
lastWasConst := false;
CheckForIncompleteStructType;
end; {else}
end; {FunctionCall}
@ -3676,6 +3694,7 @@ case tree^.token.kind of
LoadAddress(tree);
if expressionType^.kind = pointerType then
expressionType := expressionType^.ptype;
CheckForIncompleteStructType;
end;
enumConst: begin
@ -4645,7 +4664,9 @@ case tree^.token.kind of
((lType^.kind in [functionType,arrayType,structType,unionType])
or ((lType^.kind = definedType) and {handle const struct/union}
(lType^.dType^.kind in [structType,unionType]))) then
Error(79);
Error(79)
else
CheckForIncompleteStructType;
end {if}
else
Error(79);

View File

@ -802,6 +802,7 @@ if list or (numErr <> 0) then begin
184: msg := @'segment exceeds bank size';
185: msg := @'lint: unused variable: ';
186: msg := @'lint: implicit conversion changes value of constant';
187: msg := @'expression has incomplete struct or union type';
end; {case}
if extraStr <> nil then begin
extraStr^ := concat(msg^,extraStr^);