From patchwork Wed Jun 16 16:20:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 55910 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 D34ACB7D83 for ; Thu, 17 Jun 2010 02:20:48 +1000 (EST) Received: (qmail 20952 invoked by alias); 16 Jun 2010 16:20:46 -0000 Received: (qmail 20941 invoked by uid 22791); 16 Jun 2010 16:20:44 -0000 X-SWARE-Spam-Status: No, hits=-3.8 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 16 Jun 2010 16:20:38 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 0802A8891E; Wed, 16 Jun 2010 18:20:35 +0200 (CEST) Date: Wed, 16 Jun 2010 18:20:34 +0200 From: Martin Jambor To: GCC Patches Cc: Richard Guenther , Jason Merrill Subject: [PATCH, PR 44535] Fix a problem with folding OBJ_TYPE_REFs Message-ID: <20100616162034.GB19794@virgil.suse.cz> Mail-Followup-To: GCC Patches , Richard Guenther , Jason Merrill MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.17 (2007-11-01) 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, as the testcase shows, my assumption that BASE_BINFOs were reordered in a way that if any of the had virtual functions the first one did too was false. I do not really remember why I thought this, I must have misunderstood results of some experiments I did last autumn. The following patch fixes the folding by skipping BASE_BINFOs that do not have virtual functions when looking for the "first" one. In addition to the request for an approval of the patch, I also have one question. I believe it would be quite desirable to have a sanity check in gimple_fold_obj_type_ref_known_binfo asserting that BINFO_FLAG_2 is true. In in the c++ front end this bit is referred to as BINFO_NEW_VTABLE_MARKED. Should I move the definition of this macro from gcc/cp/cp-tree.h to gcc/tree.h so that we can use it for the assert too? Would such a patch be accepted? As usual, I have bootstrapped and tested the patch on x86_64-linux, OK for trunk? Thanks, Martin 2010-06-16 Martin Jambor PR c++/44535 * gimple-fold.c (get_first_base_binfo_with_virtuals): New function. (gimple_get_relevant_ref_binfo): Use get_first_base_binfo_with_virtuals instead of BINFO_BASE_BINFO. * testsuite/g++.dg/torture/pr44535.C: New file. Index: icln/gcc/gimple-fold.c =================================================================== --- icln.orig/gcc/gimple-fold.c +++ icln/gcc/gimple-fold.c @@ -1403,6 +1403,22 @@ 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. */ @@ -1458,8 +1474,8 @@ gimple_get_relevant_ref_binfo (tree ref, || BINFO_N_BASE_BINFOS (binfo) == 0) return NULL_TREE; - base_binfo = BINFO_BASE_BINFO (binfo, 0); - if (BINFO_TYPE (base_binfo) != TREE_TYPE (field)) + base_binfo = get_first_base_binfo_with_virtuals (binfo); + if (base_binfo && BINFO_TYPE (base_binfo) != TREE_TYPE (field)) { tree d_binfo; Index: icln/gcc/testsuite/g++.dg/torture/pr44535.C =================================================================== --- /dev/null +++ icln/gcc/testsuite/g++.dg/torture/pr44535.C @@ -0,0 +1,34 @@ +/* { dg-do run } */ + +namespace FOO { + +template +class A +{ +public: + void Enum(); + virtual void OnProv() = 0; + virtual ~A() { } +}; +typedef A B; + +template +void A::Enum () +{ + OnProv (); +} +} // namespace FOO + +class C {}; + +class D: public C, public FOO::B { +public: + void OnProv() {} +}; + +int main(int argc, char *argv[]) +{ + D x; + x.Enum(); + return 0; +}