Apologies if this is a duplicate:  I searched existing reports and found tons
of hits on "virtual inheritance" and "reference", but couldn't find anything
like this.  The following program illustrates the problem:

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

struct Lower {
        const int&      ref;

        Lower(const int& ref) : ref(ref) { }
};


struct Middle : public virtual Lower {

        Middle(const int& ref) : Lower(ref) { }
};


struct Upper : public Middle {

        Upper(const int& ref) : Lower(ref), Middle(ref) { }

        int     get()
        {
                return ref;
        }
};


int     main()
{
        int i = 0;
        Upper upper(i);

        return upper.get();
}


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Compiling this using 4.2.2 or 4.2.3 with -O2 or higher causes the resulting
binary to return a non-zero value;  3.4.2 produces a bug-free binary.  I've
seen the same effect in more complex code, where gdb gives an obviously wrong
address for the "ref" member.  Dropping to -O fixes the problem, as do several
other changes:

* Making "ref" an int (as opposed to an int&)
* Making Middle inherit non-virtually from Lower
* Accessing "ref" from Middle instead of Upper

The constness of the reference has no effect.


Issued command-line:
    g++ -Wall -W -Wundef -Wpointer-arith -g -O2 VirtuallyInheritedReference.cpp

Full output from running with "-v --save-temps" is as follows:
    g++ -v -save-temps -Wall -W -Wundef -Wpointer-arith -g -O2 -c -o /dev/null
VirtuallyInheritedReference.cpp

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /mnt/taw/usr/Taw/tmp/gcc-4.2.2/configure --prefix=/usr
--disable-nls --libexecdir=/usr/lib --enable-shared --enable-threads=posix
--enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++
--disable-bootstrap
Thread model: posix
gcc version 4.2.2
 /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/cc1plus -E -quiet -v -D_GNU_SOURCE
VirtuallyInheritedReference.cpp -mtune=generic -Wall -W -Wundef -Wpointer-arith
-fworking-directory -O2 -fpch-preprocess -o VirtuallyInheritedReference.ii
ignoring nonexistent directory
"/usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../../i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../../include/c++/4.2.2

/usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../../include/c++/4.2.2/i686-pc-linux-gnu
 /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/../../../../include/c++/4.2.2/backward
 /usr/local/include
 /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/include
 /usr/include
End of search list.
 /usr/lib/gcc/i686-pc-linux-gnu/4.2.2/cc1plus -fpreprocessed
VirtuallyInheritedReference.ii -quiet -dumpbase VirtuallyInheritedReference.cpp
-mtune=generic -auxbase-strip /dev/null -g -O2 -Wall -W -Wundef -Wpointer-arith
-version -o VirtuallyInheritedReference.s
GNU C++ version 4.2.2 (i686-pc-linux-gnu)
        compiled by GNU C version 4.2.2.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 6ba594205d388e98f3b46dee442d61ac
 as -V -Qy -o /dev/null VirtuallyInheritedReference.s
GNU assembler version 2.18 (i686-pc-linux-gnu) using BFD version (GNU Binutils)
2.18
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>



Contents of VirtuallyInheritedReference.ii:

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# 1 "VirtuallyInheritedReference.cpp"
# 1 "/home/raymond/src/C++/gcc-bugs//"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "VirtuallyInheritedReference.cpp"

struct Lower {
 int& ref;

 virtual ~Lower() { }

 Lower(int& ref) : ref(ref) { }
};


struct Middle : public virtual Lower {

 Middle(int& ref) : Lower(ref) { }
};


struct Upper : public Middle {

 Upper(int& ref) : Lower(ref), Middle(ref) { }

 int get()
 {
  return ref;
 }
};


int main()
{
 int i = 0;
 Upper upper(i);

 return upper.get();
}

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


-- 
           Summary: Reference variable in virtually inherited base corrupted
                    under optimization
           Product: gcc
           Version: 4.2.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: raymond at corvil dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36960

Reply via email to