From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12758 invoked by alias); 12 Apr 2015 01:11:21 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 12747 invoked by uid 89); 12 Apr 2015 01:11:20 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL,BAYES_00,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY,T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sun, 12 Apr 2015 01:11:18 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 524AA5430BB; Sun, 12 Apr 2015 03:11:15 +0200 (CEST) Date: Sun, 12 Apr 2015 01:11:00 -0000 From: Jan Hubicka To: Jan Hubicka Cc: Martin =?iso-8859-2?Q?Li=B9ka?= , GCC Patches Subject: Re: [PATCH] Fix PR ipa/65722 Message-ID: <20150412011115.GA73158@kam.mff.cuni.cz> References: <5527F705.5020509@suse.cz> <20150410163815.GB17443@kam.mff.cuni.cz> <20150411171140.GA23919@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150411171140.GA23919@kam.mff.cuni.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2015-04/txt/msg00517.txt.bz2 Hi, this is version of patch I comitted after testing at x86_64-linux firefox build and bootstrapped/regtested ppc64-linux. Honza Jan Hubicka Martin Liska PR ipa/65722 * g++.dg/ipa/pr65722.C: New testcase. * ipa-icf.c (sem_item::compare_cgraph_references): function and variable can not match. (sem_item::update_hash_by_addr_refs): Fix handling of virtual tables. (sem_variable::equals_wpa): Fix checking of DECL_FINAL_P patch. Index: testsuite/g++.dg/ipa/pr65722.C =================================================================== --- testsuite/g++.dg/ipa/pr65722.C (revision 0) +++ testsuite/g++.dg/ipa/pr65722.C (revision 0) @@ -0,0 +1,21 @@ +// { dg-do compile } +// { dg-options "-O -fipa-icf -fno-rtti" } + +struct A +{ + virtual void f () + { + __builtin_abort (); + } + virtual void g (); +}; + +struct B : virtual A { }; +struct C : B, virtual A { }; + +void foo() +{ + C c; + C *p = &c; + p->f (); +} Index: ipa-icf.c =================================================================== --- ipa-icf.c (revision 221977) +++ ipa-icf.c (working copy) @@ -368,6 +368,10 @@ sem_item::compare_cgraph_references ( if (n1 == n2) return true; + /* Never match variable and function. */ + if (is_a (n1) != is_a (n2)) + return false; + /* Merging two definitions with a reference to equivalent vtables, but belonging to a different type may result in ipa-polymorphic-call analysis giving a wrong answer about the dynamic type of instance. */ @@ -587,9 +591,6 @@ void sem_item::update_hash_by_addr_refs (hash_map &m_symtab_node_map) { - if (is_a (node) && DECL_VIRTUAL_P (node->decl)) - return; - ipa_ref* ref; inchash::hash hstate (hash); for (unsigned i = 0; i < node->num_references (); i++) @@ -1667,17 +1668,19 @@ sem_variable::equals_wpa (sem_item *item ref->address_matters_p ())) return false; - /* DECL_FINAL_P flag on methods referred by virtual tables is used - to decide on completeness possible_polymorphic_call_targets lists - and therefore it must match. */ - if ((DECL_VIRTUAL_P (decl) || DECL_VIRTUAL_P (item->decl)) - && (DECL_VIRTUAL_P (ref->referred->decl) - || DECL_VIRTUAL_P (ref2->referred->decl)) - && ((DECL_VIRTUAL_P (ref->referred->decl) - != DECL_VIRTUAL_P (ref2->referred->decl)) - || (DECL_FINAL_P (ref->referred->decl) - != DECL_FINAL_P (ref2->referred->decl)))) - return return_false_with_msg ("virtual or final flag mismatch"); + /* When matching virtual tables, be sure to also match information + relevant for polymorphic call analysis. */ + if (DECL_VIRTUAL_P (decl) || DECL_VIRTUAL_P (item->decl)) + { + if (DECL_VIRTUAL_P (ref->referred->decl) + != DECL_VIRTUAL_P (ref2->referred->decl)) + return return_false_with_msg ("virtual flag mismatch"); + if (DECL_VIRTUAL_P (ref->referred->decl) + && is_a (ref->referred) + && (DECL_FINAL_P (ref->referred->decl) + != DECL_FINAL_P (ref2->referred->decl))) + return return_false_with_msg ("final flag mismatch"); + } } return true;