Allow access to fields from all struct-typed expressions.

This affects field selection expressions where the left expressions is a struct/union assignment or a function call returning a struct or union. Such expressions should be accepted, but they were giving spurious errors.

The following program illustrates the problem:

struct S {int a,b;} x, y={2,3};

struct S f(void) {
        struct S s = {7,8};
        return s;
}

int main(void) {
        return f().a + (x=y).b;
}
This commit is contained in:
Stephen Heumann 2021-09-17 22:04:10 -05:00
parent 650ff4697f
commit 1b9955bf8b
2 changed files with 9 additions and 3 deletions

View File

@ -2911,7 +2911,8 @@ var
end; {if}
end {else if}
else if ExpressionKind(tree) in [arrayType,pointerType] then
else if ExpressionKind(tree) in [arrayType,pointerType,structType,unionType]
then
GenerateCode(tree)
else begin
expressionType := intPtr; {set default type in case of error}
@ -4461,8 +4462,11 @@ case tree^.token.kind of
opminusminus: {postfix --}
DoIncDec(tree^.left, pc_lld, pc_gld, pc_ild);
uand: {unary & (address operator)}
uand: begin {unary & (address operator)}
if not (tree^.left^.token.kind in [ident,uasterisk]) then
L_Value(tree^.left);
LoadAddress(tree^.left);
end; {case uand}
uasterisk: begin {unary * (indirection)}
GenerateCode(tree^.left);
@ -4493,7 +4497,7 @@ case tree^.token.kind of
dotch: begin {.}
LoadAddress(tree^.left);
lType := expressionType;
if lType^.kind in [arrayType,pointerType] then begin
if lType^.kind in [arrayType,pointerType,structType,unionType] then begin
if lType^.kind = arrayType then
lType := lType^.aType
else if lType^.kind = pointerType then

View File

@ -1230,6 +1230,8 @@ int foo(int[42]);
165. When assigning to multiple structures or unions using successive = operators (e.g. s1=s2=s3), assignments other than the rightmost one might store incorrect values, depending on the size of the structures or unions.
166. The fields of structures and unions should be accessible from any expression of structure or union type, including assignments and function calls. For example, if x and y have type "struct S {int i;}", then (x=y).i is a legal expression that performs an assignment and then gets the value of the i field. Similarly, f().i is a legal expression if the function call f() has a return type of struct S. These expressions were not being accepted, but now they are.
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
1. In some situations, fread() reread the first 1K or so of the file.