From patchwork Mon Apr 22 20:58:45 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 238669 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 F0BDD2C0123 for ; Tue, 23 Apr 2013 06:58:55 +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:content-type; q= dns; s=default; b=s1MX8SbWRUyxxGGUTaLB8K5Zb5RhLSm6/eQy1LZhm43P6Y H9ctu6/NmPrrc9KCbBOWjPQk9lK4PhegL6FrwvO2OE/AYGnvdL0rYZepf7JCc/IQ uEo0nXNp+zhaOPhidGgBRymn+YylgCg9EXrbWF4GCE0sWD6BF0XJB2T5j72Uk= 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:content-type; s= default; bh=CHIXDxqJPrMEukqYXqUhfmD/4Aw=; b=XsT7XIhexp/Pek9HDoZh Mh4saNSj7SJavo3rGMxyRlCrEJtJP10g4sTwjzNMlUJjm9O03WDslVoXFGpgmD7Z gD9ArzOYCfz8Znu72hKpJzMsaUbFs7i5USLFHDEpi+84q2Qx9H5Q8tWxbPakoLRI KdSCQBpt9ohSPtbyx3goOp0= Received: (qmail 19403 invoked by alias); 22 Apr 2013 20:58:49 -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 19392 invoked by uid 89); 22 Apr 2013 20:58:49 -0000 X-Spam-SWARE-Status: No, score=-6.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_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, 22 Apr 2013 20:58:48 +0000 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3MKwlMR003476 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 22 Apr 2013 16:58:47 -0400 Received: from [10.36.116.23] (ovpn-116-23.ams2.redhat.com [10.36.116.23]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r3MKwjX1002281 for ; Mon, 22 Apr 2013 16:58:46 -0400 Message-ID: <5175A485.6030207@redhat.com> Date: Mon, 22 Apr 2013 16:58:45 -0400 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: C++ PATCH to support ~auto X-Virus-Found: No In discussion of core issue 1586 at the Bristol meeting, someone suggested that we should remove ~decltype(expr) and instead allow ~auto. This patch implements that, currently limited to C++1y mode. Tested x86_64-pc-linux-gnu, applying to trunk. commit 37c8b2edbc39b6b6278afc08f7b74ace79743c5d Author: Jason Merrill Date: Tue Apr 16 22:33:08 2013 +0100 Core 1586 * parser.c (cp_parser_unqualified_id): Handle ~auto. (cp_parser_pseudo_destructor_name): Likewise. (cp_parser_postfix_dot_deref_expression): Adjust. (cp_lexer_nth_token_is_keyword): New. * semantics.c (finish_pseudo_destructor_expr): Handle ~auto. * typeck.c (lookup_destructor): Handle ~auto. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1fbc9bd..0456dd2 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -866,6 +866,12 @@ cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword) return cp_lexer_peek_token (lexer)->keyword == keyword; } +static inline bool +cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword) +{ + return cp_lexer_peek_nth_token (lexer, n)->keyword == keyword; +} + /* Return true if the next token is not the indicated KEYWORD. */ static inline bool @@ -1860,7 +1866,7 @@ static vec *cp_parser_parenthesized_expression_list /* Values for the second parameter of cp_parser_parenthesized_expression_list. */ enum { non_attr = 0, normal_attr = 1, id_attr = 2 }; static void cp_parser_pseudo_destructor_name - (cp_parser *, tree *, tree *); + (cp_parser *, tree, tree *, tree *); static tree cp_parser_unary_expression (cp_parser *, bool, bool, cp_id_kind *); static enum tree_code cp_parser_unary_operator @@ -4821,6 +4827,17 @@ cp_parser_unqualified_id (cp_parser* parser, return build_nt (BIT_NOT_EXPR, scope); } + /* ~auto means the destructor of whatever the object is. */ + if (cp_parser_is_keyword (token, RID_AUTO)) + { + if (cxx_dialect < cxx1y) + pedwarn (input_location, 0, + "%<~auto%> only available with " + "-std=c++1y or -std=gnu++1y"); + cp_lexer_consume_token (parser->lexer); + return build_nt (BIT_NOT_EXPR, make_auto ()); + } + /* If there was an explicit qualification (S::~T), first look in the scope given by the qualification (i.e., S). @@ -6171,18 +6188,18 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, cp_parser_parse_tentatively (parser); /* Parse the pseudo-destructor-name. */ s = NULL_TREE; - cp_parser_pseudo_destructor_name (parser, &s, &type); + cp_parser_pseudo_destructor_name (parser, postfix_expression, + &s, &type); if (dependent_p && (cp_parser_error_occurred (parser) - || TREE_CODE (type) != TYPE_DECL - || !SCALAR_TYPE_P (TREE_TYPE (type)))) + || !SCALAR_TYPE_P (type))) cp_parser_abort_tentative_parse (parser); else if (cp_parser_parse_definitely (parser)) { pseudo_destructor_p = true; postfix_expression = finish_pseudo_destructor_expr (postfix_expression, - s, TREE_TYPE (type)); + s, type); } } @@ -6443,11 +6460,28 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, static void cp_parser_pseudo_destructor_name (cp_parser* parser, + tree object, tree* scope, tree* type) { bool nested_name_specifier_p; + /* Handle ~auto. */ + if (cp_lexer_next_token_is (parser->lexer, CPP_COMPL) + && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_AUTO) + && !type_dependent_expression_p (object)) + { + if (cxx_dialect < cxx1y) + pedwarn (input_location, 0, + "%<~auto%> only available with " + "-std=c++1y or -std=gnu++1y"); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + *scope = NULL_TREE; + *type = TREE_TYPE (object); + return; + } + /* Assume that things will not work out. */ *type = error_mark_node; @@ -6515,7 +6549,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser, /* Look for the type-name again. We are not responsible for checking that it matches the first type-name. */ - *type = cp_parser_nonclass_name (parser); + *type = TREE_TYPE (cp_parser_nonclass_name (parser)); } /* Parse a unary-expression. diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 2b8ceb2..d4f0f82 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2373,6 +2373,8 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor) error ("invalid qualifying scope in pseudo-destructor name"); return error_mark_node; } + if (is_auto (destructor)) + destructor = TREE_TYPE (object); if (scope && TYPE_P (scope) && !check_dtor_name (scope, destructor)) { error ("qualified type %qT does not match destructor name ~%qT", diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 50405c3..c0696e0 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2483,7 +2483,9 @@ lookup_destructor (tree object, tree scope, tree dtor_name, scope, dtor_type); return error_mark_node; } - if (identifier_p (dtor_type)) + if (is_auto (dtor_type)) + dtor_type = object_type; + else if (identifier_p (dtor_type)) { /* In a template, names we can't find a match for are still accepted destructor names, and we check them here. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-dtor1.C b/gcc/testsuite/g++.dg/cpp1y/auto-dtor1.C new file mode 100644 index 0000000..7105095 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-dtor1.C @@ -0,0 +1,22 @@ +// DR 1586 +// { dg-options "-std=c++1y" } +// { dg-do run } + +template +void f (T* p) +{ + p->~auto(); +} + +int d; +struct A { ~A() { ++d; } }; + +int main() +{ + f(new int(42)); + f(new A); + if (d != 1) + throw; + + (new int)->~auto(); +}