From patchwork Mon Nov 1 15:49:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 69792 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 10DC9B70FC for ; Tue, 2 Nov 2010 02:49:36 +1100 (EST) Received: (qmail 22506 invoked by alias); 1 Nov 2010 15:49:32 -0000 Received: (qmail 22492 invoked by uid 22791); 1 Nov 2010 15:49:31 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI X-Spam-Check-By: sourceware.org Received: from cantor.suse.de (HELO mx1.suse.de) (195.135.220.2) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 01 Nov 2010 15:49:25 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 4BE425362F; Mon, 1 Nov 2010 16:49:23 +0100 (CET) Date: Mon, 1 Nov 2010 16:49:22 +0100 From: Martin Jambor To: GCC Patches Cc: Richard Guenther , Jason Merrill Subject: [PATCH, PR 45875] Devirtualization with virtual inheritace Message-ID: <20101101154922.GC16393@virgil.arch.suse.de> Mail-Followup-To: GCC Patches , Richard Guenther , Jason Merrill MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, at the summit I have discussed with Jason how to detect the correct primary base classes (so that I can ignore them) and thanks to him I know that zero offset is the correct thing to test. This patch does exactly that which means it fixes PR 45875. Bootstrapped and tested on x86_64-linux, also passes make-c++ on i686-linux. OK for trunk? Thanks, Martin 2010-10-27 Martin Jambor PR tree-optimization/45875 * gimple-fold.c (get_first_base_binfo_with_virtuals): Removed. (gimple_get_relevant_ref_binfo): Detect primary bases according to their field offset. * testsuite/g++.dg/torture/pr45875.C: New test. Index: icln/gcc/gimple-fold.c =================================================================== --- icln.orig/gcc/gimple-fold.c +++ icln/gcc/gimple-fold.c @@ -1360,22 +1360,6 @@ gimple_fold_builtin (gimple stmt) return result; } -/* Return the first of the base binfos of BINFO that has virtual functions. */ - -static tree -get_first_base_binfo_with_virtuals (tree binfo) -{ - int i; - tree base_binfo; - - for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - if (BINFO_VIRTUALS (base_binfo)) - return base_binfo; - - return NULL_TREE; -} - - /* Search for a base binfo of BINFO that corresponds to TYPE and return it if it is found or NULL_TREE if it is not. */ @@ -1413,7 +1397,7 @@ gimple_get_relevant_ref_binfo (tree ref, if (TREE_CODE (ref) == COMPONENT_REF) { tree par_type; - tree binfo, base_binfo; + tree binfo; tree field = TREE_OPERAND (ref, 1); if (!DECL_ARTIFICIAL (field)) @@ -1431,14 +1415,15 @@ gimple_get_relevant_ref_binfo (tree ref, || BINFO_N_BASE_BINFOS (binfo) == 0) return NULL_TREE; - base_binfo = get_first_base_binfo_with_virtuals (binfo); - if (base_binfo && BINFO_TYPE (base_binfo) != TREE_TYPE (field)) + /* Do not use the BINFO of the primary base class, use the + descendant's instead. */ + if (int_bit_position (field) != 0) { tree d_binfo; + /* Get descendant binfo. */ d_binfo = gimple_get_relevant_ref_binfo (TREE_OPERAND (ref, 0), known_binfo); - /* Get descendant binfo. */ if (!d_binfo) return NULL_TREE; return get_base_binfo_for_type (d_binfo, TREE_TYPE (field)); Index: icln/gcc/testsuite/g++.dg/torture/pr45875.C =================================================================== --- /dev/null +++ icln/gcc/testsuite/g++.dg/torture/pr45875.C @@ -0,0 +1,25 @@ +// { dg-do compile } + +struct c1 {}; + +struct c10 : c1 +{ + virtual void foo (); +}; + +struct c11 : c10, c1 // // { dg-warning "" } +{ + virtual void f6 (); +}; + +struct c28 : virtual c11 +{ + void f6 (); +}; + +void check_c28 () +{ + c28 obj; + c11 *ptr = &obj; + ptr->f6 (); +}