This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
Hi!
glibc is miscompiled by GCC 4.0+, a regression from 3.4.x.
The problem is that if there is an automatic struct variable
with flexible array member, but not all other fields initialized,
when being gimplified the gimplifier initializes just the explicitely
initialized fields, but not the rest of the struct.
See testcase in the first patch.
The problem is that for such structs count_type_elements returns -1
and gimplify_init_constructor does not handle initializers that don't
have all fields explicitely initialized when cleared is false.
The first patch fixes that, but might pessimize constructors of
structures with flexible array member where all fields but the
flexible array members are explicitely initialized. So the second
patch on top of the first one attempts to deal with that (on the
20050613-2.c testcase the second patch removes severeal unnecessary
stores of 0).
Ok for HEAD/4.0? Mark, would this be appropriate for 4.0.1,
as it is a wrong-code bug that causes miscompilation of quite important
package (glibc)?
BTW: there are other things that need consideration in
gimplify_init_constructors. E.g. for
extern void abort (void);
#define M1(n) int m##n##0; int m##n##1; int m##n##2; int m##n##3; int m##n##4;
#define M2(n) M1(n##0) M1(n##1) M1(n##2) M1(n##3) M1(n##4)
#define M3(n) M2(n##0) M2(n##1) M2(n##2) M2(n##3) M2(n##4)
#define N1(n) , .m##n##0 = 1##n##0, .m##n##1 = 1##n##1, .m##n##2 = 1##n##2, .m##n##3 = 1##n##3, .m##n##4 = 1##n##4
#define N2(n) N1(n##0) N1(n##1) N1(n##2) N1(n##3) N1(n##4)
#define N3(n) N2(n##0) N2(n##1) N2(n##2) N2(n##3) N2(n##4)
void foo (void *x);
struct C { int i; int j; int k; int l; M3(0) M3(1) int r[0]; };
struct D { int i; int j; int k; int l; M3(0) M3(1) int r[]; };
int
bar ()
{
struct C c = { .j = 5 N3(0) N3(1) };
foo (&c);
return 0;
}
int
baz ()
{
struct D d = { .j = 5 N3(0) N3(1) };
foo (&d);
return 0;
}
we used to create the var in .rodata and memcpy it in, but now
we create a huge chunk of zeros in .rodata, memcpy it in and afterwards
initialize all the explicitely initialized non-zero struct members.
Jakub
Attachment:
R1
Description: Text document
Attachment:
R21
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |