This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/12326] New: Thunk not generated for virtual func
- From: "thomas at koeller dot dyndns dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 18 Sep 2003 09:59:44 -0000
- Subject: [Bug c++/12326] New: Thunk not generated for virtual func
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12326
Summary: Thunk not generated for virtual func
Product: gcc
Version: 3.3
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: thomas at koeller dot dyndns dot org
CC: gcc-bugs at gcc dot gnu dot org,thomas dot koeller at
baslerweb dot com
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
If both -fvtable-gc and -ffunction-sections are given to the compiler and the linker (GNU ld)
is invoked with --gc-sections, then virtual functions are eliminated in spite of being called,
and no thunks are generated for these functions either. A set of files to reproduce the
problem is included at the end of this PR.
When the program is built with the Makefile included, the output from nm shows that
neither the function Drvd::func2() nor a thunk for it is present in the executable. Its vtable
slot is zeroed and the program segfaults.
bash-2.05b$ nm -C testprog | grep '.*::func'
08048298 T Drvd::func1()
bash-2.05b$ testprog
Segmentation fault
bash-2.05b$
If I leave out -fvtable-gc, then the output from nm looks ok and the program runs fine.
bash-2.05b$ nm -C testprog | grep '.*::func'
08048298 T Drvd::func1()
0804829e T Drvd::func2()
080482a4 W non-virtual thunk to Drvd::func2()
bash-2.05b$ testprog
bash-2.05b$
These are the files to reproduce the bug (why can't I just attach a tar.bz2 archive?):
Makefile:
-----------------------------------------------------------------------------------------------------------------------------
APPNAME := testprog
CXX := /opt/gcc/bin/g++
CXXFLAGS := -O0 -ggdb2 -fno-rtti -ffunction-sections -fdata-sections \
-fvtable-gc
LD := $(CXX)
LDFLAGS := -static -O0 -Wl,-Map -Wl,$(APPNAME).map -Wl,--gc-sections
RM := rm
RMFLAGS := -f
.PHONY : all clean
all : $(APPNAME)
$(APPNAME) : testprog.o drvd.o
$(LD) $(LDFLAGS) -o $@ $^
testprog.o : testprog.cxx testprog.hxx
$(CXX) $(CXXFLAGS) -c -o $@ $<
drvd.o : drvd.cxx testprog.hxx
$(CXX) $(CXXFLAGS) -c -o $@ $<
clean :
$(RM) $(RMFLAGS) testprog.o drvd.o $(APPNAME) $(APPNAME).map
-----------------------------------------------------------------------------------------------------------------------------
testprog.hxx:
-----------------------------------------------------------------------------------------------------------------------------
#if !defined (TESTPROG_HXX)
#define TESTPROG_HXX
class Base1
{
public:
virtual void func1(void) = 0;
};
class Base2
{
public:
virtual void func2(void) = 0;
};
class Drvd : public Base1, public Base2
{
public:
virtual void func1(void);
virtual void func2(void);
};
#endif // !defined (TESTPROG_HXX)
-----------------------------------------------------------------------------------------------------------------------------
testprog.cxx:
-----------------------------------------------------------------------------------------------------------------------------
#include "testprog.hxx"
Drvd drvd;
int
main(void)
{
Base1 &base1(drvd);
Base2 &base2(drvd);
base1.func1();
base2.func2();
return 0;
};
-----------------------------------------------------------------------------------------------------------------------------
drvd.cxx:
-----------------------------------------------------------------------------------------------------------------------------
#include "testprog.hxx"
void
Drvd::func1(void)
{
}
void
Drvd::func2(void)
{
}
-----------------------------------------------------------------------------------------------------------------------------