[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #11 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- I'm not going to discuss whether my example is a valid C code or not, but in FORTRAN it goes a similarly wrong way. The compiler treats incorrectly the one-element array in a common.
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #12 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- Created attachment 30740 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30740action=edit Example of failing FORTRAN code, with assembler output from gfortran 4.6.4
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #1 from Florian Weimer fweimer at redhat dot com --- The compiler is free to assume that both i1 and i2 are zero and the first store is dead (because this is the only valid array index). So if the buggy() function stores a value of 1.0 at mem.dmem[0] unconditionally, this is still correct. struct { double dmem[1]; /* Change to dmem[2] and the bug disappears */ } mem; void buggy(int i1, int i2) { mem.dmem[i1] = 0.5; mem.dmem[i2] = 1.; }
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #2 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- OK, I'm not and expert, but mem is a global structure and it can be of different size in other object file. The linker should assume the biggest of all, correct? The example I posted comes from f2c-translated FORTRAN77 code (it is cleared from f2c references). It was a normal practice to mix C with FORTRAN for dynamic memory allocation. The memory allocated via malloc() was referenced to a small (one-element) static array. There was nothing illegal with this. And how can the compiler assume freely that both i1 and i2 are zeros, if they are passed as actual arguments?
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #3 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- The compiler option -fno-tree-dse does the job for me. Florian - thank you for using the term dead store ;). I'm not sure whether it should be enabled by default for a C compiler, but I'm not competent enough even to suggest a solution.
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #4 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- Unfortunately, this is not the end of story. I'm going to attach a little more complicated example, for which even using -fno-dse -fno-tree-dse does not help.
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #5 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- Created attachment 30719 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30719action=edit Second example, not working also with -fno-tree-dse -fno-dse
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #6 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- Created attachment 30720 -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=30720action=edit File containing main() for the second example
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #7 from Mikael Pettersson mikpe at it dot uu.se --- Your examples are invalid C. In one module you present the compiler with a specific declaration, and complain when it utilizes constraints derived from that declaration. Then in another module you have an _incompatible_ declaration for the same object. You can't expect to get away with that, even if it seemed to work with an older compiler. You should use a C99 flexible array member, or a pointer (to an array of unknown size).
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #8 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- Mikael, I cannot agree. Do not look at main.c, as the compiler doesn't know anything about it while compiling buggy.c (this is the reason for which I keep main() separately) and doesn't know that i1, i2 and i3 may be set to something 0 at runtime. If it would be so much strict about declarations, it wouldn't also allow to modify mem.dmem[1] - everything would go into mem.dmem[0]. However, it writes mem.dmem[1] only (!) if compiled without -fno-tree-dse and mem.dmem[0] plus mem.dmem[1] with -fno-tree-dse. The problem is that the compiler does not work predictably. BTW, correct size of the mem structure (global variable) is ensured by the linker: $ nm buggy.o T buggy 000c C loc 0008 C mem I would also expect that if the compiler is instructed explicitly to release some constraints, then these will be released.
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 Jakub Jelinek jakub at gcc dot gnu.org changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED CC||jakub at gcc dot gnu.org Resolution|--- |INVALID --- Comment #9 from Jakub Jelinek jakub at gcc dot gnu.org --- You are confusing how C/C++ commons work with how Fortran commons work. Your examples are simply invalid C/C++.
[Bug c/58270] Wrong code while accessing array elements in a global structure
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58270 --- Comment #10 from Krzysztof Strasburger strasbur at chkw386 dot ch.pwr.wroc.pl --- Jakub, I do not care about C++ (never understood it), but commons are just commons. I see them from linker's perspective. How does the compiler treat variables belonging to that common - this is a different story. I examined the assembler outputs and I think that the real problem is that the compiler treats one-element array (dmem) in buggy.c as ordinary variable. somewhere. If dmem is declared as two-element array (so that nobody can assume blindly to which element data should go), then everything works correctly, regardless how it is declared elsewhere. It is an overoptimization IMHO, but I'm just a user.