[gnu.g++.bug] g++ 1.34.0 sparc bug

jjc@UUNET.UU.NET (James Clark) (03/12/89)

g++ 1.34.0 (test release of Mar 3) configured for the SPARC on a Sun 4/110
running Sun OS 4.0 generates code that incorrectly causes a bus error.

Script started on Sun Mar 12 09:00:33 1989
jclark% cat bug.c

struct foo {
	double x;
	foo();
};

foo::foo()
{
  x = 1.0;
}

static foo f;

main()
{
  exit(0);
}
jclark% g++ -g -v bug.c
g++ version 1.34.0
 /usr/local/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ bug.c /tmp/cca03381.cpp
GNU CPP version 1.34
 /usr/local/lib/gcc-c++ /tmp/cca03381.cpp -quiet -dumpbase bug.c -g -version -o /tmp/cca03381.s
GNU C++ version 1.34.0 (sparc) compiled by GNU C version 1.34.
 as /tmp/cca03381.s -o bug.o
 /usr/local/lib/gcc-ld++ -C -e start -dc -dp /usr/local/lib/crt0+.o bug.o -lg++ /usr/local/lib/gcc-gnulib -lg -lc
jclark% a.out
Bus error (core dumped)
jclark% gdb a.out core
GDB 3.1, Copyright (C) 1988 Free Software Foundation, Inc.
There is ABSOLUTELY NO WARRANTY for GDB; type "info warranty" for details.
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "info copying" to see the conditions.
Reading symbol data from /u/jjc/groff/a.out...done.
Core file is from "a.out".
Program terminated with signal 10, Bus error.
Type "help" for a list of commands.
(gdb) frame
#0  0x2164 in foo ($this=(struct foo *) 0x6584) (bug.c line 9)
9	  x = 1.0;
(gdb) quit
jclark% exit
jclark% 

jjc@UUNET.UU.NET (James Clark) (03/12/89)

I have looked further at the bug I reported to you earlier today (with
g++ 1.34.0 on the SPARC). It turns out to be a problem with ld++
If you compile and run the following, you'll see the problem.

static double x;

main()
{
  x = 1.0;
}

What happens is that the bss segment ends up being aligned
on a 4-byte boundary, which causes the program to generate
a bus error on execution.

The following diff seems to fix this problem:

*** ld.c.distrib	Sat Feb 25 21:41:56 1989
--- ld.c	Sun Mar 12 11:37:27 1989
***************
*** 2189,2194 ****
--- 2189,2195 ----
    outheader.a_text += N_ADDRADJ (outheader);
  #endif
  
+   data_size = (data_size + sizeof(double) - 1) & ~(sizeof(double)-1);
    /* Make the data segment address start in memory on a suitable boundary.  */
  
    data_start = N_DATADDR (outheader) + text_start - N_TXTADDR (outheader);

I don't really understand ld too well, so this may not be a
good fix, but it seems to work for me.