From patchwork Mon Apr 15 15:18:39 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 236635 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 976882C00DC for ; Tue, 16 Apr 2013 01:18:56 +1000 (EST) 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:subject:references :in-reply-to:content-type; q=dns; s=default; b=iCq09stvvNuwDOUUg RX6FpODIgua/W+ko0JlYJvXAQFf3/hvB3eLSejIiGLbohQIwhULnyKSwm7Dw9qT/ ZAaBa8ZVrFRUfsck6zNuBsqAcatXlPeNpw/uaO8vwdPOcUBdcvymoY5mvQBnP40i 1tsHrE7G42LgbTEGH8IvqQX7C4= 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:subject:references :in-reply-to:content-type; s=default; bh=xr1pphwV2WWGUi9BoqWm9pN XZng=; b=c2Sa8DNFXoBOjIyVJm0nPyERImO6toEd3nxily7t/IUQxoGEkaqgKwI BQmsl7zAT/yGqP2scsev6bzr9gnJlM3xLlIx1z5/xxkBgEGhzhWFHHRpis83djzi a4LAHtOOhPAPn4TKRmhnGGdZVA2ylGaVnopiZQb1QrErpbM++VOo= Received: (qmail 15543 invoked by alias); 15 Apr 2013 15:18:42 -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 15506 invoked by uid 89); 15 Apr 2013 15:18:42 -0000 X-Spam-SWARE-Status: No, score=-7.5 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 15 Apr 2013 15:18:41 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3FFIe0d010276 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 15 Apr 2013 11:18:40 -0400 Received: from [10.3.113.35] (ovpn-113-35.phx2.redhat.com [10.3.113.35]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r3FFIdYH005979 for ; Mon, 15 Apr 2013 11:18:39 -0400 Message-ID: <516C1A4F.1010608@redhat.com> Date: Mon, 15 Apr 2013 16:18:39 +0100 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:22.0) Gecko/20100101 Thunderbird/22.0a2 MIME-Version: 1.0 To: gcc-patches List Subject: Re: Another C++ PATCH for c++/52748 (N3276 and operator overloading) References: <51671422.6030304@redhat.com> In-Reply-To: <51671422.6030304@redhat.com> X-Virus-Found: No On 04/11/2013 08:50 PM, Jason Merrill wrote: > My earlier N3276 work only affected the function call syntax, but it > needs to affect implicit function calls from overloaded operators as well. ...and in templates. Tested x86_64-pc-linux-gnu, applying to trunk and 4.8. commit 9448b41e5f5a64a2a92519049898fba4c9d43633 Author: Jason Merrill Date: Sat Apr 13 21:12:45 2013 +0200 PR c++/52748 * pt.c (tsubst) [DECLTYPE_TYPE]: If ~id is an expression rather than a destructor name, it isn't an unqualified-name. (tsubst_copy_and_build): Pass down decltype_flag to operator handling code, too. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0c7b2ed..5c960e0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11800,8 +11800,17 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) else if (DECLTYPE_FOR_LAMBDA_PROXY (t)) type = lambda_proxy_type (type); else - type = finish_decltype_type - (type, DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t), complain); + { + bool id = DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t); + if (id && TREE_CODE (DECLTYPE_TYPE_EXPR (t)) == BIT_NOT_EXPR + && EXPR_P (type)) + /* In a template ~id could be either a complement expression + or an unqualified-id naming a destructor; if instantiating + it produces an expression, it's not an id-expression or + member access. */ + id = false; + type = finish_decltype_type (type, id, complain); + } return cp_build_qualified_type_real (type, cp_type_quals (t) | cp_type_quals (type), @@ -13427,9 +13436,8 @@ tsubst_copy_and_build (tree t, /* N3276 decltype magic only applies to calls at the top level or on the right side of a comma. */ - if (TREE_CODE (t) != CALL_EXPR - && TREE_CODE (t) != COMPOUND_EXPR) - complain &= ~tf_decltype; + tsubst_flags_t decltype_flag = (complain & tf_decltype); + complain &= ~tf_decltype; switch (TREE_CODE (t)) { @@ -13517,7 +13525,8 @@ tsubst_copy_and_build (tree t, r = convert_from_reference (r); } else - r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR, complain); + r = build_x_indirect_ref (input_location, r, RO_UNARY_STAR, + complain|decltype_flag); RETURN (r); } @@ -13594,7 +13603,8 @@ tsubst_copy_and_build (tree t, case POSTINCREMENT_EXPR: op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); - RETURN (build_x_unary_op (input_location, TREE_CODE (t), op1, complain)); + RETURN (build_x_unary_op (input_location, TREE_CODE (t), op1, + complain|decltype_flag)); case PREDECREMENT_EXPR: case PREINCREMENT_EXPR: @@ -13606,7 +13616,8 @@ tsubst_copy_and_build (tree t, case REALPART_EXPR: case IMAGPART_EXPR: RETURN (build_x_unary_op (input_location, TREE_CODE (t), - RECUR (TREE_OPERAND (t, 0)), complain)); + RECUR (TREE_OPERAND (t, 0)), + complain|decltype_flag)); case FIX_TRUNC_EXPR: RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)), @@ -13623,7 +13634,8 @@ tsubst_copy_and_build (tree t, else op1 = tsubst_non_call_postfix_expression (op1, args, complain, in_decl); - RETURN (build_x_unary_op (input_location, ADDR_EXPR, op1, complain)); + RETURN (build_x_unary_op (input_location, ADDR_EXPR, op1, + complain|decltype_flag)); case PLUS_EXPR: case MINUS_EXPR: @@ -13672,7 +13684,7 @@ tsubst_copy_and_build (tree t, ? ERROR_MARK : TREE_CODE (TREE_OPERAND (t, 1))), /*overload=*/NULL, - complain); + complain|decltype_flag); if (EXPR_P (r) && TREE_NO_WARNING (t)) TREE_NO_WARNING (r) = TREE_NO_WARNING (t); @@ -13688,7 +13700,8 @@ tsubst_copy_and_build (tree t, op1 = tsubst_non_call_postfix_expression (TREE_OPERAND (t, 0), args, complain, in_decl); RETURN (build_x_array_ref (EXPR_LOCATION (t), op1, - RECUR (TREE_OPERAND (t, 1)), complain)); + RECUR (TREE_OPERAND (t, 1)), + complain|decltype_flag)); case SIZEOF_EXPR: if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) @@ -13781,7 +13794,7 @@ tsubst_copy_and_build (tree t, RECUR (TREE_OPERAND (t, 0)), TREE_CODE (TREE_OPERAND (t, 1)), RECUR (TREE_OPERAND (t, 2)), - complain); + complain|decltype_flag); /* TREE_NO_WARNING must be set if either the expression was parenthesized or it uses an operator such as >>= rather than plain assignment. In the former case, it was already @@ -13870,7 +13883,7 @@ tsubst_copy_and_build (tree t, RETURN (build_x_compound_expr (EXPR_LOCATION (t), op0, RECUR (TREE_OPERAND (t, 1)), - complain)); + complain|decltype_flag)); } case CALL_EXPR: @@ -13882,10 +13895,6 @@ tsubst_copy_and_build (tree t, bool koenig_p; tree ret; - /* Don't pass tf_decltype down to subexpressions. */ - tsubst_flags_t decltype_flag = (complain & tf_decltype); - complain &= ~tf_decltype; - function = CALL_EXPR_FN (t); /* When we parsed the expression, we determined whether or not Koenig lookup should be performed. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C b/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C index 1d12b01..27797a2 100644 --- a/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C +++ b/gcc/testsuite/g++.dg/cpp0x/decltype-call3.C @@ -43,6 +43,50 @@ A operator==(B,B); A operator->*(B,B); #define TRY(E) static_cast(0) + +template +void f() +{ + B b; + TRY(b(0)); + TRY(b[0]); + TRY(b=0); + TRY(b+=0); + TRY(b-=0); + TRY(b*=0); + TRY(b/=0); + TRY(b^=0); + TRY(b&=0); + TRY(b|=0); + TRY(b<<=0); + TRY(b>>=0); + + TRY(-b); + TRY(+b); + TRY(*b); + TRY(&b); + TRY(!b); + TRY(~b); + TRY(++b); + TRY(--b); + + TRY(b+b); + TRY(b-b); + TRY(b*b); + TRY(b/b); + TRY(b%b); + TRY(b^b); + TRY(b&b); + TRY(b|b); + TRY(b>b); + TRY(b>b); + TRY(b==b); + TRY(b->*b); +} + int main() { B b; @@ -83,4 +127,6 @@ int main() TRY(b>>b); TRY(b==b); TRY(b->*b); + + f(); }