From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8682 invoked by alias); 23 May 2002 19:56:01 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 8653 invoked by uid 71); 23 May 2002 19:56:00 -0000 Resent-Date: 23 May 2002 19:56:00 -0000 Resent-Message-ID: <20020523195600.8652.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-To: nobody@gcc.gnu.org Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org, spencer@aol.net Resent-Reply-To: gcc-gnats@gcc.gnu.org, spencer@aol.net Received:(qmail 32413 invoked by uid 61); 23 May 2002 19:46:47 -0000 Message-Id:<20020523194647.32408.qmail@sources.redhat.com> Date: Thu, 23 May 2002 12:56:00 -0000 From: spencer@aol.net Reply-To: spencer@aol.net To: gcc-gnats@gcc.gnu.org Cc: spencer@aol.net X-Send-Pr-Version:gnatsweb-2.9.3 (1.1.1.1.2.31) X-GNATS-Notify:spencer@aol.net Subject: c++/6788: multiple inheritance "non-virtual thunk" assembly incorrect on sparc64-sun-solars2.8 X-SW-Source: 2002-05/txt/msg00750.txt.bz2 List-Id: >Number: 6788 >Category: c++ >Synopsis: multiple inheritance "non-virtual thunk" assembly incorrect on sparc64-sun-solars2.8 >Confidential: no >Severity: critical >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Thu May 23 12:56:00 PDT 2002 >Closed-Date: >Last-Modified: >Originator: Brad Spencer >Release: gcc-3.1 >Organization: >Environment: sparc64-sun-solaris (64-bit compile) More details in description >Description: It looks like invalid assembly is being generated for multiple inhertiance where the member data is "big" (i.e. it takes two SPARC assembly instructions to move the this pointer). The code that's generated looks like it would be right if the registers were 32-bit, but they're not, so it ends up adding a positive (big) number to the this pointer instead of adding a negative (small) number. I've included code and a walkthough with gdb-5.2 to show how the code could be corrected. Assembler warnings often (but don't always?) accompany this problem. The small test case I've included in the "How-to-repeat" section does cause assembler warnings. >How-To-Repeat: netra-map1:~$ cat foo.cc //***************************************************************************** // $Id$ static const char *st_ID __attribute__((unused)) = "$Id$"; class Base { public: Base() {} virtual void baseFunc() = 0; char waste[16 * 1024]; }; class Other { public: Other() {} virtual void func() = 0; char waste[16 * 1024]; }; void caller(Other &other) { other.func(); } class Sub : public Base, private Other { public: Sub() : Base(), Other() {} void preCaller() { caller(*this); } private: virtual void func() { member = 1; } virtual void baseFunc() { member = 2; } int member; }; int main() { Sub sub; sub.preCaller(); return 0; } //***************************************************************************** netra-map1:~$ uname -a SunOS netra-map1 5.8 Generic_108528-09 sun4u sparc SUNW,UltraAX-i2 netra-map1:~$ psrinfo -v Status of processor 0 as of: 05/23/02 16:33:20 Processor has been on-line since 05/22/02 11:11:40. The sparcv9 processor operates at 500 MHz, and has a sparcv9 floating point processor. netra-map1:~$ g++ -v -m64 -Wall -g -o foo foo.cc Reading specs from /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/specs Configured with: ../gcc-3.1/configure --with-dwarf2 --enable-languages=c,c++ --enable-threads=single --disable-shared --with-gnu-as --with-gnu-ld --with-as=/opt/bin/as --with-ld=/opt/bin/ld --prefix=/opt/gcc-3.1 Thread model: single gcc version 3.1 /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/cc1plus -v -iprefix /opt/bin/../lib/gcc-lib/sparc-sun-solaris2.8/3.1/ -D__GNUC__=3 -D__GNUC_MINOR__=1 -D__GNUC_PATCHLEVEL__=0 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__PRAGMA_REDEFINE_EXTNAME -D__sparc__ -D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__PRAGMA_REDEFINE_EXTNAME -D__sparc -D__sun -D__unix -Asystem=unix -Asystem=svr4 -D__NO_INLINE__ -D__STDC_HOSTED__=1 -D_XOPEN_SOURCE=500 -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 -D__EXTENSIONS__ -D__SIZE_TYPE__=long unsigned int -D__PTRDIFF_TYPE__=long int -D__WCHAR_TYPE__=int -D__WINT_TYPE__=int -D__arch64__ -Acpu=sparc64 -Amachine=sparcv9 -D__sparcv9 foo.cc -D__GNUG__=3 -D__DEPRECATED -D__EXCEPTIONS -D__GXX_ABI_VERSION=100 -mptr64 -mstack-bias -mno-v8plus -mcpu=v9 -quiet -dumpbase foo.cc -m64 -g -Wall -version -o /var/tmp//ccp2mt4M.s GNU CPP version 3.1 (cpplib) (sparc ELF) GNU C++ version 3.1 (sparc-sun-solaris2.8) compiled by GNU C version 3.1. ignoring nonexistent directory "/opt/lib/gcc-lib/sparc-sun-solaris2.8/3.1/../../../../include/g++-v3" ignoring nonexistent directory "/opt/lib/gcc-lib/sparc-sun-solaris2.8/3.1/../../../../include/g++-v3/sparc-sun-solaris2.8" ignoring nonexistent directory "/opt/lib/gcc-lib/sparc-sun-solaris2.8/3.1/../../../../include/g++-v3/backward" ignoring nonexistent directory "/opt/lib/gcc-lib/sparc-sun-solaris2.8/3.1/include" ignoring nonexistent directory "/opt/lib/gcc-lib/sparc-sun-solaris2.8/3.1/../../../../sparc-sun-solaris2.8/include" ignoring nonexistent directory "/usr/local/include" ignoring nonexistent directory "/opt/gcc-3.1/sparc-sun-solaris2.8/include" #include "..." search starts here: #include <...> search starts here: /opt/gcc-3.1/include/g++-v3 /opt/gcc-3.1/include/g++-v3/sparc-sun-solaris2.8 /opt/gcc-3.1/include/g++-v3/backward /opt/gcc-3.1/include /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/include /usr/include End of search list. /opt/bin/as -V -Qy -s -64 -Av9 -o /var/tmp//ccGfY3zI.o /var/tmp//ccp2mt4M.s GNU assembler version 2.11.2 (sparc-sun-solaris2.8) using BFD version 2.11.2 /var/tmp//ccp2mt4M.s: Assembler messages: /var/tmp//ccp2mt4M.s:290: Warning: set: number not in 0..4294967295 range /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/collect2 -V -m elf64_sparc -Y P,/usr/lib/sparcv9 -Qy -o foo /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/sparcv9/crt1.o /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/sparcv9/crti.o /usr/lib/sparcv9/values-Xa.o /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/sparcv9/crtbegin.o -L/opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/sparcv9 -L/opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1 -L/usr/ccs/bin/sparcv9 -L/usr/ccs/bin -L/usr/ccs/lib/sparcv9 -L/usr/ccs/lib -L/opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/../../../sparcv9 -L/opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/../../.. -L/lib/sparcv9 -L/usr/lib/sparcv9 /var/tmp//ccGfY3zI.o -lstdc++ -lm -lgcc -lc -lgcc -lc /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/sparcv9/crtend.o /opt/gcc-3.1/lib/gcc-lib/sparc-sun-solaris2.8/3.1/sparcv9/crtn.o GNU ld version 2.11.2 (with BFD 2.11.2) Supported emulations: elf32_sparc elf64_sparc netra-map1:~$ ./foo Segmentation Fault (core dumped) netra-map1:~$ gdb ./foo core GNU gdb 5.2 Copyright 2002 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "sparc64-sun-solaris2.8"... Core was generated by `./foo'. Program terminated with signal 11, Segmentation fault. Reading symbols from /usr/lib/64/libm.so.1...done. Loaded symbols for /usr/lib/64/libm.so.1 Reading symbols from /usr/lib/64/libc.so.1...done. Loaded symbols for /usr/lib/64/libc.so.1 Reading symbols from /usr/lib/64/libdl.so.1...done. Loaded symbols for /usr/lib/64/libdl.so.1 Reading symbols from /usr/platform/SUNW,UltraAX-i2/lib/sparcv9/libc_psr.so.1...done. Loaded symbols for /usr/platform/SUNW,UltraAX-i2/lib/sparcv9/libc_psr.so.1 #0 0x100006180 in Sub::func() (this=0x7fff7810) at foo.cc:37 37 virtual void func() { member = 1; } (gdb) bt #0 0x100006180 in Sub::func() (this=0x7fff7810) at foo.cc:37 #1 0x100000bd0 in caller(Other&) (other=@0xffffffff7fffb818) at foo.cc:26 #2 0x1000060ec in Sub::preCaller() (this=0xffffffff7fff7810) at foo.cc:34 #3 0x100000c18 in main () at foo.cc:49 (gdb) b main Breakpoint 1 at 0x100000be8: file foo.cc, line 47. (gdb) r Starting program: /export/spare/live/spencer/foo Breakpoint 1, main () at foo.cc:47 47 Sub sub; (gdb) n 49 sub.preCaller(); (gdb) s Sub::preCaller() (this=0xffffffff7fff7840) at foo.cc:34 34 void preCaller() { caller(*this); } (gdb) s caller(Other&) (other=@0xffffffff7fffb848) at foo.cc:26 26 other.func(); (gdb) s 0x100006190 in non-virtual thunk to Sub::func() () at foo.cc:37 37 virtual void func() { member = 1; } (gdb) disass Dump of assembler code for function _ZThn16392_N3Sub4funcEv: 0x100006190 <_ZThn16392_N3Sub4funcEv>: sethi %hi(0xffffbc00), %g1 0x100006194 <_ZThn16392_N3Sub4funcEv+4>: or %g1, 0x3f8, %g1 ! 0xffffbff8 0x100006198 <_ZThn16392_N3Sub4funcEv+8>: add %o0, %g1, %o0 0x10000619c <_ZThn16392_N3Sub4funcEv+12>: mov %o7, %g1 0x1000061a0 <_ZThn16392_N3Sub4funcEv+16>: call 0x100006168 <_ZN3Sub4funcEv> 0x1000061a4 <_ZThn16392_N3Sub4funcEv+20>: mov %g1, %o7 End of assembler dump. (gdb) p/x $o0 $1 = 0xffffffff7fffb848 (gdb) p/x $g1 $2 = 0xffffffffffff7f20 (gdb) si 0x100006194 37 virtual void func() { member = 1; } (gdb) si 0x100006198 37 virtual void func() { member = 1; } (gdb) p/x $g1 $3 = 0xffffbff8 (gdb) si 0x10000619c 37 virtual void func() { member = 1; } (gdb) p/x $o0 $4 = 0x7fff7840 (gdb) c Continuing. Program received signal SIGSEGV, Segmentation fault. 0x100006180 in Sub::func() (this=0x7fff7840) at foo.cc:37 37 virtual void func() { member = 1; } (gdb) r The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /export/spare/live/spencer/foo Breakpoint 1, main () at foo.cc:47 47 Sub sub; (gdb) n 49 sub.preCaller(); (gdb) s Sub::preCaller() (this=0xffffffff7fff7840) at foo.cc:34 34 void preCaller() { caller(*this); } (gdb) s caller(Other&) (other=@0xffffffff7fffb848) at foo.cc:26 26 other.func(); (gdb) s 0x100006190 in non-virtual thunk to Sub::func() () at foo.cc:37 37 virtual void func() { member = 1; } (gdb) disass Dump of assembler code for function _ZThn16392_N3Sub4funcEv: 0x100006190 <_ZThn16392_N3Sub4funcEv>: sethi %hi(0xffffbc00), %g1 0x100006194 <_ZThn16392_N3Sub4funcEv+4>: or %g1, 0x3f8, %g1 ! 0xffffbff8 0x100006198 <_ZThn16392_N3Sub4funcEv+8>: add %o0, %g1, %o0 0x10000619c <_ZThn16392_N3Sub4funcEv+12>: mov %o7, %g1 0x1000061a0 <_ZThn16392_N3Sub4funcEv+16>: call 0x100006168 <_ZN3Sub4funcEv> 0x1000061a4 <_ZThn16392_N3Sub4funcEv+20>: mov %g1, %o7 End of assembler dump. (gdb) si 0x100006194 37 virtual void func() { member = 1; } (gdb) si 0x100006198 37 virtual void func() { member = 1; } (gdb) si 0x10000619c 37 virtual void func() { member = 1; } (gdb) p/x $o0 $5 = 0x7fff7840 (gdb) set $o0 = 0xffffffff7fff7840 (gdb) p/x $o0 $6 = 0xffffffff7fff7840 (gdb) c Continuing. Program exited normally. (gdb) quit >Fix: >Release-Note: >Audit-Trail: >Unformatted: