Fix issues where static initialization may generate the wrong number of bytes.

This relates to unions or structs that are "filled" with zeros because the initializer does not include explicit terms for them, and that contain bit-fields or (for unions) do not start with the longest member.

The following program is an example that was miscompiled:

#include <stdio.h>

struct BF {
        int i:3;
        int j:4;
};

union U {
        int i;
        long l;
};

struct Outer1 {
        int n;
        struct BF bf[7];
        union U u[5];
};

struct Outer2 {
        long p;
        struct Outer1 o1;
        long q;
};

int main(void) {
        static struct Outer2 s = {1,{0},212};
        printf("%li %li\n", s.p, s.q);
}
This commit is contained in:
Stephen Heumann 2018-09-14 19:02:21 -05:00
parent 4d10fbae01
commit fedd275395

View File

@ -2211,20 +2211,28 @@ var
else if tp^.kind = structType then begin
{fill a structure}
i := count;
while i <> 0 do begin
ip := tp^.fieldList;
while ip <> nil do begin
Fill(1, ip^.iType);
ip := ip^.next;
if variable^.storage in [external,global,private] then
Fill(count * tp^.size, bytePtr)
else begin
i := count;
while i <> 0 do begin
ip := tp^.fieldList;
while ip <> nil do begin
Fill(1, ip^.iType);
ip := ip^.next;
end; {while}
i := i-1;
end; {while}
i := i-1;
end; {while}
end; {else}
end {else if}
else if tp^.kind = unionType then
else if tp^.kind = unionType then begin
{fill a union}
Fill(count, tp^.fieldList^.iType)
if variable^.storage in [external,global,private] then
Fill(count * tp^.size, bytePtr)
else
Fill(count, tp^.fieldList^.iType);
end {else if}
else
{fill a single value}