From patchwork Fri Jan 23 15:27:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 432194 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DDB261401F6 for ; Sat, 24 Jan 2015 02:27:18 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=lnriqF/vvi0PmetR+7nhkjW4/JslK9lRqIwjtSzI6dh Pp1QWwOoY5h2nY/mEPPFj2PeutvQ1R3eRwthb/p1vGNlSceX7bhQm0bd9hn4Z+BO yipCzG5JGHqW8z2XRdu/CrLOYdIjR0+dhR1OW4/rWXFVRknAgA5hTP3kHlGlOVwI = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=8pZWXDrnIItmEiYxoYXOOQdLnrA=; b=TGuw9HtlxK2IfVdxe 9802pkK2KhqYmJSR1Ha62C6c9rdnIuhSqaq6dDRAPy5p8r8GmIP9nnnqMt4au4BG 3E/cHZXE4X6TSQdHTh7FC8xoSNy1obTExrSoVA/XKAXjsBeBlOarSYhKbcL4fMaB dEI0DtQETdUxa1CiKHLPgPqLGc= Received: (qmail 14794 invoked by alias); 23 Jan 2015 15:27:10 -0000 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 Received: (qmail 14755 invoked by uid 89); 23 Jan 2015 15:27:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Fri, 23 Jan 2015 15:27:04 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 3FD00AB43; Fri, 23 Jan 2015 15:27:01 +0000 (UTC) Message-ID: <54C26845.8000101@suse.cz> Date: Fri, 23 Jan 2015 16:27:01 +0100 From: =?UTF-8?B?TWFydGluIExpxaFrYQ==?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches CC: "hubi >> Jan Hubicka" Subject: Fix PR ipa/64693 X-IsSubscribed: yes Hello. Following patch is a fix for PR ipa/64693, where ICF merges a pair of functions that somehow take a references to a different functions. Unfortunately, such function pointer can be used for function comparison that can break an executable. Tested on x86_64-linux-pc and no regression is added. Apart from that, I'm able to run tests on LTO bootstraped compiler. Ready for trunk? Thanks, Martin From ff65c1bb4ba1593ea42aec5d6cbedf2330d8a866 Mon Sep 17 00:00:00 2001 From: mliska Date: Fri, 23 Jan 2015 14:58:36 +0100 Subject: [PATCH] Fix PR ipa/64693. gcc/ChangeLog: 2015-01-23 Martin Liska PR ipa/64693 * ipa-icf.c (sem_function::equals_private): Handle references for a pair of compared functions. gcc/testsuite/ChangeLog: 2015-01-23 Martin Liska * gcc.dg/ipa/ipa-icf-26.c: Fix expected results. * gcc.dg/ipa/ipa-icf-33.c: Remove reduced line. * gcc.dg/ipa/ipa-icf-34.c: New test. --- gcc/ipa-icf.c | 27 +++++++++++++++++++++- gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c | 3 +-- gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c | 1 - gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c | 43 +++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index afb5be5..4bea08d 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -525,13 +525,38 @@ sem_function::equals_private (sem_item *item, if (decl1 != decl2) return return_false(); - for (arg1 = DECL_ARGUMENTS (decl), arg2 = DECL_ARGUMENTS (m_compared_func->decl); arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2)) if (!m_checker->compare_decl (arg1, arg2)) return return_false (); + /* Compare if this function contains any function references + and compare them. */ + cgraph_node *source_node = get_node (); + cgraph_node *target_node = m_compared_func->get_node (); + if (source_node->num_references () != target_node->num_references ()) + return return_false_with_msg ("different number of references"); + + ipa_ref *r1 = NULL, *r2 = NULL; + + for (unsigned i = 0; i < source_node->num_references (); i++) + { + symtab_node *ref1 = source_node->iterate_reference (i, r1)->referred; + symtab_node *ref2 = target_node->iterate_reference (i, r2)->referred; + + bool is_cgraph1 = is_a (ref1); + bool is_cgraph2 = is_a (ref2); + + if (!is_cgraph1 && !is_cgraph2) + continue; + + if ((is_cgraph1 && is_cgraph2 && ref1 != ref2) + || (!is_cgraph1 && is_cgraph2) + || (is_cgraph1 && !is_cgraph2)) + return return_false_with_msg ("different target of a reference"); + } + /* Fill-up label dictionary. */ for (unsigned i = 0; i < bb_sorted.length (); ++i) { diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c index 0c5a5a6..f48c040 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c @@ -38,7 +38,6 @@ int main() return 0; } -/* { dg-final { scan-ipa-dump "Semantic equality hit:bar->foo" "icf" } } */ /* { dg-final { scan-ipa-dump "Semantic equality hit:remove->destroy" "icf" } } */ -/* { dg-final { scan-ipa-dump "Equal symbols: 2" "icf" } } */ +/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf" } } */ /* { dg-final { cleanup-ipa-dump "icf" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c index d7e814d..7b6a8ae 100644 --- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c @@ -23,5 +23,4 @@ int main() } /* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf" } } */ -/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf" } } */ /* { dg-final { cleanup-ipa-dump "icf" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c new file mode 100644 index 0000000..c8507c7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-34.c @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -fipa-icf -fdump-ipa-icf-details" } */ + +#include +#include + +int callback1(int a) +{ + return a * a; +} + +int callback2(int a) +{ + return a * a; +} + +static int test(int (*callback) (int)) +{ + if (callback == callback1) + return 1; + + return 0; +} + +int foo() +{ + return test(&callback1); +} + +int bar() +{ + return test(&callback2); +} + +int main() +{ + assert (foo() != bar()); + + return 0; +} + +/* { dg-final { scan-ipa-dump "different target of a reference" "icf" } } */ +/* { dg-final { cleanup-ipa-dump "icf" } } */ -- 2.1.2