From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10132 invoked by alias); 15 Dec 2013 21:40:44 -0000 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org Received: (qmail 10096 invoked by uid 48); 15 Dec 2013 21:40:41 -0000 From: "hubicka at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug ipa/59226] [4.9 Regression] ICE: in record_target_from_binfo, at ipa-devirt.c:661 Date: Sun, 15 Dec 2013 21:40:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: ipa X-Bugzilla-Version: 4.9.0 X-Bugzilla-Keywords: ice-on-valid-code X-Bugzilla-Severity: normal X-Bugzilla-Who: hubicka at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Priority: P1 X-Bugzilla-Assigned-To: hubicka at gcc dot gnu.org X-Bugzilla-Target-Milestone: 4.9.0 X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2013-12/txt/msg01319.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59226 --- Comment #7 from Jan Hubicka --- This testcase manifest the other virtual inehritance problem. Here it is algorithm of get_binfo_at_offset that first walks fields of a structure and if it finds corresponding field at given offset, it walks bases of structure to dive recursively into. I am speaking of testcase in #1 Here get_binfo_at_offset is called on binfo of class D looking for class A at offset 0. The binfo of class D itself is one nested in E. The inheritance tree looks as follows: A B v/v\ / (v marks virtual inheritance) C D \ / E ipa-devirt does not expect get_binfo_at_offset to fail since it knows D derives A. Now get_binfo_at_offset looks into memory layout of type D. constant 128> unit size constant 16> align 64 symtab 0 alias set -1 canonical type 0x7ffff76b17e0 fields unit size align 64 symtab 0 alias set -1 canonical type 0x7ffff76a87e0 fields context full-name "struct B" needs-constructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown pointer_to_this chain > ignored decl_6 BLK file /home/jan/t.C line 13 col 8 size unit size align 64 offset_align 128 offset bit offset context chain nonlocal decl_4 VOID file /home/jan/t.C line 14 col 1 align 1 context result chain >> context full-name "struct D" needs-constructor X() X(constX&) this=(X&) n_parents=2 use_template=0 interface-unknown pointer_to_this chain > and here it finds B that is a wrong turn and gives up after looking into B. Now if it looked further (gdb) p debug_tree (fld->common.chain->common.chain) unit size align 64 symtab 0 alias set -1 canonical type 0x7ffff76a8000 fields unsigned virtual DI file /home/jan/t.C line 1 col 8 size unit size align 64 offset_align 128 offset bit offset context chain > context full-name "struct A" needs-constructor X() X(constX&) this=(X&) n_parents=0 use_template=0 interface-unknown pointer_to_this chain > ignored decl_6 BLK file /home/jan/t.C line 13 col 8 size unit size align 64 offset_align 128 offset bit offset context > $20 = void here it would find A, but this time at offset 64. So perhaps we are looking for A at wrong offset? Or are we taking wrong vtable? type_binfo is D since it is last on the walk down to A with virtual table attached. Maybe it is because all references to A in D go via C's vtable and we are safe to give up. Or do we need to compensate for offsets here like this? Index: ipa-devirt.c =================================================================== --- ipa-devirt.c (revision 205941) +++ ipa-devirt.c (working copy) @@ -646,8 +646,11 @@ if (types_same_for_odr (type, outer_type)) { - tree inner_binfo = get_binfo_at_offset (type_binfo, - offset, otr_type); + tree inner_binfo = get_binfo_at_offset + (type_binfo, offset + + (tree_to_uhwi (BINFO_OFFSET (type_binfo)) + - tree_to_uhwi (BINFO_OFFSET (binfo))) + * BITS_PER_UNIT, otr_type); /* For types in anonymous namespace first check if the respective vtable is alive. If not, we know the type can't be called. */ if (!flag_ltrans && anonymous) (in single inheritance case this is not needed, since every binfo with non-zero offset must have vtable attached). Other option would be to simply return NULL when inner_binfo is NULL with a comment that this is virtual multiple inheritance case where vtable was already taken care on at different branch of recursion. Jason, what do you think? Markus, I do not have my usual firefox testing setup until christmas. Would be nice to know if the proposed patch works on anything else than this testcase.