diff options
| author | Philip <pipcet@gmail.com> | 2015-04-25 19:17:37 +0000 |
|---|---|---|
| committer | Philip <pipcet@gmail.com> | 2015-04-25 19:25:23 +0000 |
| commit | 8d44851d6582ddb753f9cfc273c872a4164189df (patch) | |
| tree | e2dacf62bf02b958e6fda411ca5fbcc1507497fd | |
| parent | 1dd3f88f3b847554d3bb8117b5dd5640c4be1ccf (diff) | |
| download | tinycc-8d44851d6582ddb753f9cfc273c872a4164189df.tar.gz tinycc-8d44851d6582ddb753f9cfc273c872a4164189df.tar.bz2 | |
Fix zero-length struct/union test. Remove nonsensical test.
The comment suggests this was meant to detect unions, but in fact it
compared f->c, the union/struct size, against f->next->c, the first
element's offset.
This affected only zero-length structs/unions with a first (zero-length)
element, as in this code:
struct u2 {
};
struct u {
struct u2 u2;
} u;
struct u f(struct u x)
{
return x;
}
However, such structures turned out to be broken anyway, as code like this
was generated for the above f:
0000000000000000 <f>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 81 ec 10 00 00 00 sub $0x10,%rsp
b: 66 0f d6 45 f8 movq %xmm0,-0x8(%rbp)
10: 66 0f 6e 45 f8 movd -0x8(%rbp),%xmm0
15: e9 00 00 00 00 jmpq 1a <f+0x1a>
1a: c9 leaveq
1b: c3 retq
| -rw-r--r-- | x86_64-gen.c | 6 |
1 files changed, 1 insertions, 5 deletions
diff --git a/x86_64-gen.c b/x86_64-gen.c index d837a1d..90c8247 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -1066,12 +1066,8 @@ static X86_64_Mode classify_x86_64_inner(CType *ty) case VT_STRUCT: f = ty->ref; - // Detect union - if (f->next && (f->c == f->next->c)) - return x86_64_mode_memory; - mode = x86_64_mode_none; - for (; f; f = f->next) + for (f = f->next; f; f = f->next) mode = classify_x86_64_merge(mode, classify_x86_64_inner(&f->type)); return mode; |
