From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4656 invoked by alias); 22 Nov 2003 14:46:48 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 4643 invoked by uid 48); 22 Nov 2003 14:46:47 -0000 Date: Sat, 22 Nov 2003 14:46:00 -0000 Message-ID: <20031122144647.4642.qmail@sources.redhat.com> From: "grigory at stl dot sarov dot ru" To: gcc-bugs@gcc.gnu.org In-Reply-To: <20031119083730.13118.grigory@stl.sarov.ru> References: <20031119083730.13118.grigory@stl.sarov.ru> Reply-To: gcc-bugzilla@gcc.gnu.org Subject: [Bug c++/13118] [ABI] Missed covariant return thunk X-Bugzilla-Reason: CC X-SW-Source: 2003-11/txt/msg02000.txt.bz2 List-Id: ------- Additional Comments From grigory at stl dot sarov dot ru 2003-11-22 14:46 ------- There is another example illustrating the same problem. In the hierarchy listed below, c3 shares virtual table both with c2 and c1 bases. That is c3 v-table introduces 3 slots for covariant return type function "foo". First and second slots contain pointer to adjustment thunks and third one contains pointer to non-adjusting entry. [0] c1-in-c2-in-c3::foo, returning r1-in-r3 [1] c2-in-c3::foo, returning r2-in-r3 [2] c3::foo, returning r3-in-r3 However the actually generated vtable for c3 contains pointer to wrong thunk in the first slot: [skip] 16 c3::_ZTcv0_n12_v0_n12_N2c33fooEv 20 c3::_ZTcv0_n12_v0_n12_N2c33fooEv 24 c3::foo Basing on thunk encoding "v0_n12_v0_n12_", contents of c3's and r3's virtual tables we can say that "this" value will be incorrectly adjusted to c2-in-c3 and the return value will be adjusted to r2 instead of r1 in the r3's hierarchy. I.e. actually used thunk appears to be: c1-in-c2::foo, returning r1-in-r2 It looks like g++ 3.4 compiler just inherits this slot value from the vtable of base class c2 introduced as complete object. Vtable for c2 [skip] 16 c2::_ZTcv0_n12_v0_n12_N2c23fooEv 20 c2::foo Class hierarchy --------------- struct r1 { int j; virtual ~r1(); }; struct r2 : virtual r1 { int j; virtual ~r2(); }; struct r3 : virtual r2, virtual r1 { int i; }; struct c1 { virtual r1& foo() {}; }; struct c2 : virtual c1 { virtual r2& foo() {}; }; struct c3 : c2 { virtual r3& foo() {}; }; -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=13118