This code is undefined because of alignment requirments differences
for the structs and the union.
Sent from my iPhone
On Jul 3, 2009, at 6:33 PM, "dentongosnell at yahoo dot com" <gcc-bugzi...@gcc.gnu.org
> wrote:
$ gcc -v
Using built-in specs.
Target: sparc-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.3.2-1.1
'
--with-bugurl=file:///usr/share/doc/gcc-4.3/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-
shared
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/
include/c++/4.3
--program-suffix=-4.3 --enable-clocale=gnu --enable-libstdcxx-debug
--enable-objc-gc --enable-mpfr --with-cpu=v8 --with-long-double-128
--enable-checking=release --build=sparc-linux-gnu --host=sparc-linux-
gnu
--target=sparc-linux-gnu
Thread model: posix
gcc version 4.3.2 (Debian 4.3.2-1.1)
To trigger the bug :-
$ gcc align_bug.c
$ ./a.out
Bus error
$
Here is align_bug.c :-
---------
#include <stdio.h>
struct b_one {
int i;
double d;
};
struct b_two {
int i1;
int i2;
};
union myblock {
struct b_one one;
struct b_two two;
};
void myfunc(union myblock *dp1, union myblock *dp2)
{
dp2->two = dp1->two;
}
int main()
{
int w;
struct b_two a = {1,2};
struct b_two b;
myfunc((union myblock *)&a, (union myblock *)&b);
printf("%d %d\n", b.i1, b.i2);
return 0;
}
----------
The problem seems to happen in "myfunc" when the compiled code tries
to copy the 8-byte structure dp2->two to dp1->two, using a ldd/std
instruction pair. The problem seems to be that dp1 and dp2 (ie a and
b in main) aren't strictly enough aligned for that. If you take out
the redundant "int w" in main then a and b happen to be aligned okay
and the bus error doesn't happen.
I think the compiler is assuming "union myblock" has the same
alignment as "struct b_one", which is more strictly aligned than
"struct b_two" because of its double member.
I realise that casting &a to (union myblock*) in main may technically
invoke undefined behaviour... but I think the cast is reasonable given
that union myblock contains the type of a.
One other thing, there is a flag "-mno-faster-structs" which this page
suggests would prevent this sort of ldd/std use
(http://gcc.gnu.org/onlinedocs/gcc/SPARC-Options.html). Unfortunately
this flag doesn't seem to make any difference to this case.
--
Summary: Bus error caused by ldd/std instructions in
struct copy.
Product: gcc
Version: 4.3.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: dentongosnell at yahoo dot com
GCC build triplet: sparc-linux-gnu
GCC host triplet: sparc-linux-gnu
GCC target triplet: sparc-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40645