From patchwork Thu Mar 29 22:26:36 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 149507 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 C00C1B6EE6 for ; Fri, 30 Mar 2012 09:30:19 +1100 (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=1333665021; 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=6BBY+czEYFgMO7NRI5w8ONze6JU=; b=hBApgdI1WqKHklyGRoMnQhbyT3btyhD0LUUtny4NZCVe+BK3eNzRt4x3tPV9KU g/RmOUKJNquvy9yJNXr14m7R+m00I98lSLC1LotUgwe4fU0/IFqDZLSKAmpvANPI 8QdDbuZUKl3FzrvV7zmFg/2VCYTL29vhijqVIciziorDs= 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=JGSEJTex//c2BrV5IDc6QSeHu1T616E3LYpMBLhpHo7BqzvB+AZ9XtPBw5uof4 K8aLEo5OjiqqQkDXMbB060uJCYu31/pXPUo5vgq138Yusk77NPuXgNtKu7MdMIXH 19oTq1/hMGZ/AFC2hAw3DQF8lNwJl+LCErwB00aW6ot1k=; Received: (qmail 6442 invoked by alias); 29 Mar 2012 22:30:09 -0000 Received: (qmail 6428 invoked by uid 22791); 29 Mar 2012 22:30:06 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, TW_CX, TW_FN, TW_KF, 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, 29 Mar 2012 22:29:50 +0000 Received: from ucsinet21.oracle.com (ucsinet21.oracle.com [156.151.31.93]) by rcsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q2TMTmrf011770 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 29 Mar 2012 22:29:49 GMT Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by ucsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q2TMTlkA007904 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Thu, 29 Mar 2012 22:29:47 GMT Received: from abhmt111.oracle.com (abhmt111.oracle.com [141.146.116.63]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q2TMTkV2008040; Thu, 29 Mar 2012 17:29:46 -0500 Received: from [192.168.1.4] (/79.33.223.181) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 29 Mar 2012 15:29:45 -0700 Message-ID: <4F74E19C.9040903@oracle.com> Date: Fri, 30 Mar 2012 00:26:36 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:11.0) Gecko/20120312 Thunderbird/11.0 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: Re: [C++ RFC / Patch] Implementing "Deducing "noexcept" for destructors" References: <4F70515C.2090701@oracle.com> <4F70C403.5030005@redhat.com> <4F73280F.9040804@oracle.com> <4F732BC3.1050504@redhat.com> <4F73937A.50806@oracle.com> <4F74AF37.8080408@redhat.com> <4F74B2CA.6060209@oracle.com> <4F74B7A1.5070101@redhat.com> In-Reply-To: <4F74B7A1.5070101@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 03/29/2012 09:27 PM, Jason Merrill wrote: > On 03/29/2012 03:06 PM, Paolo Carlini wrote: >>> The exception specification on old_decl doesn't matter; we can drop >>> that test. >> I seem to remember something going wrong with templates otherwise, >> because implicitly_declare_fn has gcc_assert (!dependent_type_p (type)); > > We shouldn't be doing this for templates anyway, as in general we > can't know what the implicitly declared function will look like. Oh my, as simple as the below appears to work! I simply added a !processing_template_decl check. Then I removed the deduce_noexcept_on_destructor calls in register_specialization and when I found a proper place in grokfndecl (must be before check_explicit_specialization) I noticed that apparently I can remove the other deduce_noexcept_on_destructor call which I had later on in grokfndecl. Thus the below passes the (updated) testsuite on x86_64-linux. I remark (once more) that whereas we accept (otherwise nothing works in, eg, the library): template struct A { ~A(); }; template A::~A() { } we reject, with a "different exception specifier" error, both: template struct A { ~A() noexcept; }; template A::~A() { } and: template struct A { ~A(); }; template A::~A() noexcept { } Over the last days I wasted a lot of time trying painfully to not reject either, but actually now I'm pretty sure that we are right to reject the former (there are exception specifiers on the declaration thus automatic deduction should not trigger at all) and probably also the latter. These cases, characterized by different situations on declaration and definition, confused me quite a bit... Anyway, I'm attaching the last iteration. Thanks again for all your help! Paolo. /////////////////////// Index: class.c =================================================================== --- class.c (revision 185977) +++ class.c (working copy) @@ -4321,6 +4321,41 @@ clone_constructors_and_destructors (tree t) clone_function_decl (OVL_CURRENT (fns), /*update_method_vec_p=*/1); } +/* Deduce noexcept for a destructor DTOR. */ + +void +deduce_noexcept_on_destructor (tree dtor) +{ + if (!TYPE_RAISES_EXCEPTIONS (TREE_TYPE (dtor))) + { + tree ctx = DECL_CONTEXT (dtor); + tree implicit_fn = implicitly_declare_fn (sfk_destructor, ctx, + /*const_p=*/false); + tree eh_spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (implicit_fn)); + TREE_TYPE (dtor) = build_exception_variant (TREE_TYPE (dtor), eh_spec); + } +} + +/* For each destructor in T, deduce noexcept: + + 12.4/3: A declaration of a destructor that does not have an + exception-specification is implicitly considered to have the + same exception-specification as an implicit declaration (15.4). */ + +static void +deduce_noexcept_on_destructors (tree t) +{ + tree fns; + + /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail + out now. */ + if (!CLASSTYPE_METHOD_VEC (t)) + return; + + for (fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns)) + deduce_noexcept_on_destructor (OVL_CURRENT (fns)); +} + /* Subroutine of set_one_vmethod_tm_attributes. Search base classes of TYPE for virtual functions which FNDECL overrides. Return a mask of the tm attributes found therein. */ @@ -4994,6 +5029,10 @@ check_bases_and_members (tree t) cant_have_const_ctor = 0; no_const_asn_ref = 0; + /* Deduce noexcept on destructors. */ + if (cxx_dialect >= cxx0x) + deduce_noexcept_on_destructors (t); + /* Check all the base-classes. */ check_bases (t, &cant_have_const_ctor, &no_const_asn_ref); Index: decl.c =================================================================== --- decl.c (revision 185977) +++ decl.c (working copy) @@ -7448,6 +7448,12 @@ grokfndecl (tree ctype, if (ctype != NULL_TREE) grokclassfn (ctype, decl, flags); + /* 12.4/3 */ + if (cxx_dialect >= cxx0x + && DECL_DESTRUCTOR_P (decl) + && !processing_template_decl) + deduce_noexcept_on_destructor (decl); + decl = check_explicit_specialization (orig_declarator, decl, template_count, 2 * funcdef_flag + Index: method.c =================================================================== --- method.c (revision 185977) +++ method.c (working copy) @@ -1444,7 +1444,7 @@ explain_implicit_non_constexpr (tree decl) reference argument or a non-const reference. Returns the FUNCTION_DECL for the implicitly declared function. */ -static tree +tree implicitly_declare_fn (special_function_kind kind, tree type, bool const_p) { tree fn; Index: cp-tree.h =================================================================== --- cp-tree.h (revision 185977) +++ cp-tree.h (working copy) @@ -4978,6 +4978,7 @@ extern void fixup_attribute_variants (tree); extern tree* decl_cloned_function_p (const_tree, bool); extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); +extern void deduce_noexcept_on_destructor (tree); /* in cvt.c */ extern tree convert_to_reference (tree, tree, int, int, tree); @@ -5264,6 +5265,8 @@ extern tree get_copy_assign (tree); extern tree get_default_ctor (tree); extern tree get_dtor (tree, tsubst_flags_t); extern tree locate_ctor (tree); +extern tree implicitly_declare_fn (special_function_kind, tree, + bool); /* In optimize.c */ extern bool maybe_clone_body (tree);