From patchwork Thu May 3 13:58:30 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 156702 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 8C929B6FAB for ; Thu, 3 May 2012 23:59:21 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1336658362; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Message-ID:Date:From:User-Agent:MIME-Version: To:CC:Subject:References:In-Reply-To:Content-Type:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=rJD7iGYZCIahaG7mzx0FEJguYvA=; b=WtVbHCcptV6dg0JSbYZT5ixaThl72Ouzc4fT/wRc6wOTbu5lx5bsj0vTuYQs8Y 4+UUtS0+kTpTjlHhIoK/4hz3DYm3t/p0vBA2YkmDyjEsYzHKGQ/f8KcpLD9WSvxz SnDkWj2Y6g0SlQd0L11p6bisZ9hGyAUfYdd2E3S6uRBdI= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=nUmbHILGR9ovyny1zXfor9ARG3DH6AilYh7dmNaPHXwG5rgEByPEVVGUT5M56t FauZhy3+Pw6ypxLSdcAomgMn/6hJOUAEq1mHOvoVVfF9/BHY+eak+Php9auVgzq6 xpnnnnx3wpWvCnCjddQ4ZAkqxFK02UoPE+cNlqjwk91WM=; Received: (qmail 16813 invoked by alias); 3 May 2012 13:59:16 -0000 Received: (qmail 16801 invoked by uid 22791); 3 May 2012 13:59:15 -0000 X-SWARE-Spam-Status: No, hits=-7.1 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_YE, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rcsinet15.oracle.com (HELO rcsinet15.oracle.com) (148.87.113.117) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 03 May 2012 13:59:02 +0000 Received: from acsinet22.oracle.com (acsinet22.oracle.com [141.146.126.238]) by rcsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q43Dx0mt013409 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 3 May 2012 13:59:01 GMT Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by acsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q43Dx0N2010785 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 3 May 2012 13:59:00 GMT Received: from abhmt119.oracle.com (abhmt119.oracle.com [141.146.116.71]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q43Dwx3Y001559; Thu, 3 May 2012 08:58:59 -0500 Received: from [192.168.1.4] (/79.33.223.52) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 03 May 2012 06:58:59 -0700 Message-ID: <4FA28F06.3080509@oracle.com> Date: Thu, 03 May 2012 15:58:30 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120421 Thunderbird/12.0 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: Re: [C++ Patch] PR 53186 References: <4FA1DEF4.60702@oracle.com> <4FA264FD.1040102@oracle.com> <4FA28362.8030600@redhat.com> In-Reply-To: <4FA28362.8030600@redhat.com> 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 On 05/03/2012 03:08 PM, Jason Merrill wrote: > What if we moved all the devirtualization logic from > build_new_method_call_1 to build_over_call? Doh, you are absolutely right, the below, very simple, appears to work well. Probably I was afraid that we could have issues with the other build_over_call callers, but in fact now I don't see why. C++ testing done, testing the library. Ok if it passes? Thanks, Paolo. PS: submitter would like to see this in 4.7.1 too... ///////////////////////// /cp 2012-05-03 Paolo Carlini PR c++/53186 * call.c (build_over_call): Handle final member functions and class types. (build_new_method_call_1): Do not handle here. /testsuite 2012-05-03 Paolo Carlini PR c++/53186 * g++.dg/other/final2.C: New. Index: cp/call.c =================================================================== --- cp/call.c (revision 187058) +++ cp/call.c (working copy) @@ -6550,6 +6550,12 @@ build_over_call (struct z_candidate *cand, int fla return error_mark_node; } + /* See if the function member or the whole class type is declared + final and the call can be devirtualized. */ + if (DECL_FINAL_P (fn) + || CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn)))) + flags |= LOOKUP_NONVIRTUAL; + /* [class.mfct.nonstatic]: If a nonstatic member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined. @@ -7418,8 +7424,7 @@ build_new_method_call_1 (tree instance, tree fns, /* Optimize away vtable lookup if we know that this function can't be overridden. */ if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL) - && (resolves_to_fixed_type_p (instance, 0) - || DECL_FINAL_P (fn) || CLASSTYPE_FINAL (basetype))) + && resolves_to_fixed_type_p (instance, 0)) flags |= LOOKUP_NONVIRTUAL; if (explicit_targs) flags |= LOOKUP_EXPLICIT_TMPL_ARGS; Index: testsuite/g++.dg/other/final2.C =================================================================== --- testsuite/g++.dg/other/final2.C (revision 0) +++ testsuite/g++.dg/other/final2.C (revision 0) @@ -0,0 +1,27 @@ +// PR c++/53186 +// { dg-options "-fdump-tree-original -std=c++11" } + +struct F1 +{ + virtual void operator()() final; + virtual operator int() final; + virtual int operator++() final; +}; + +struct F2 final +{ + virtual void operator()(); + virtual operator int(); + virtual int operator++(); +}; + +void fooF1(F1& a) { a(); int m = a; ++a; } +void fooF2(F2& a) { a(); int m = a; ++a; } + +// { dg-final { scan-tree-dump-times "F1::operator\\(\\)" 1 "original" } } +// { dg-final { scan-tree-dump-times "F1::operator int" 1 "original" } } +// { dg-final { scan-tree-dump-times "F1::operator\\+\\+" 1 "original" } } +// { dg-final { scan-tree-dump-times "F2::operator\\(\\)" 1 "original" } } +// { dg-final { scan-tree-dump-times "F2::operator int" 1 "original" } } +// { dg-final { scan-tree-dump-times "F2::operator\\+\\+" 1 "original" } } +// { dg-final { cleanup-tree-dump "original" } }