This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/36960] New: Reference variable in virtually inherited base corrupted under optimization
- From: "raymond at corvil dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 28 Jul 2008 23:57:38 -0000
- Subject: [Bug c++/36960] New: Reference variable in virtually inherited base corrupted under optimization
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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