From patchwork Wed Jun 17 22:58:19 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 486017 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 C49DB1401DA for ; Thu, 18 Jun 2015 08:59:06 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=DOtY28fC; dkim-atps=neutral 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:references :in-reply-to:content-type; q=dns; s=default; b=lNoDFdUAVbxjdnA7W XwEhlsLUYrqP5eRpriGbe1capwVW5BSzlV0IBFqFdFGKhepNMpDxoYdw18s/F80p 2NO1j96j/O5HRVUjmRS3VsBfopF8t4EVMnakVj17iPi1kWLnR7tmk4X2lmPd9P6W NStGQ4GaelFGiJRtFb+GmT3Fsk= 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:references :in-reply-to:content-type; s=default; bh=LMcEJVe2JFJ5VPVkJXIzOJq rQ3M=; b=DOtY28fCTx94E/GYU0Czgm5KHL/XRfBATTDGtML/ltT6n7jGAV62yk6 W+/x7SBSrg6bALagAhwjGjLhTTcAznv7ZBWW4X1urNVkRfG7AADG6B6y/koaESAF FtWyPNoLII5jEa/Txw3V1deSPkpLLH1FpqI58VUyQs7UN+bZp3IE= Received: (qmail 67767 invoked by alias); 17 Jun 2015 22:58:59 -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 67758 invoked by uid 89); 17 Jun 2015 22:58:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.0 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_PASS autolearn=no version=3.3.2 X-HELO: userp1040.oracle.com Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 17 Jun 2015 22:58:57 +0000 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t5HMwsCC010384 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 17 Jun 2015 22:58:55 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t5HMwsH6027275 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 17 Jun 2015 22:58:54 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t5HMwL2T031949; Wed, 17 Jun 2015 22:58:52 GMT Received: from [192.168.1.4] (/79.52.199.172) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 17 Jun 2015 15:58:21 -0700 Message-ID: <5581FB8B.6080608@oracle.com> Date: Thu, 18 Jun 2015 00:58:19 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: Re: [C++ Patch/RFC] PR 65091 References: <55796697.2050407@oracle.com> In-Reply-To: <55796697.2050407@oracle.com> X-IsSubscribed: yes Hi again, I'm finishing testing this different idea, a much bigger patch but arguably more neat: add a bool parameter to cp_parser_id_expression and then to cp_parser_unqualified_id and pass down 'true' from cp_parser_decltype_expr (this is also nicely consistent with the 'true' we are passing to cp_parser_postfix_expression and cp_parser_expression). What do you think? Thanks, Paolo. ////////////////////// Index: cp/parser.c =================================================================== --- cp/parser.c (revision 224575) +++ cp/parser.c (working copy) @@ -1953,9 +1953,10 @@ static bool cp_parser_translation_unit static tree cp_parser_primary_expression (cp_parser *, bool, bool, bool, cp_id_kind *); static tree cp_parser_id_expression - (cp_parser *, bool, bool, bool *, bool, bool); + (cp_parser *, bool, bool, bool * = NULL, + bool = false, bool = false, bool = false); static tree cp_parser_unqualified_id - (cp_parser *, bool, bool, bool, bool); + (cp_parser *, bool, bool, bool, bool, bool); static tree cp_parser_nested_name_specifier_opt (cp_parser *, bool, bool, bool, bool); static tree cp_parser_nested_name_specifier @@ -3095,8 +3096,7 @@ cp_parser_parse_and_diagnose_invalid_type_name (cp /*template_keyword_p=*/false, /*check_dependency_p=*/true, /*template_p=*/NULL, - /*declarator_p=*/true, - /*optional_p=*/false); + /*declarator_p=*/true); /* If the next token is a (, this is a function with no explicit return type, i.e. constructor, destructor or conversion op. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN) @@ -4637,9 +4637,7 @@ cp_parser_primary_expression (cp_parser *parser, = cp_parser_id_expression (parser, /*template_keyword_p=*/false, /*check_dependency_p=*/true, - &template_p, - /*declarator_p=*/false, - /*optional_p=*/false); + &template_p); if (id_expression == error_mark_node) return error_mark_node; id_expr_token = token; @@ -4821,7 +4819,8 @@ cp_parser_id_expression (cp_parser *parser, bool check_dependency_p, bool *template_p, bool declarator_p, - bool optional_p) + bool optional_p, + bool decltype_p) { bool global_scope_p; bool nested_name_specifier_p; @@ -4865,7 +4864,8 @@ cp_parser_id_expression (cp_parser *parser, unqualified_id = cp_parser_unqualified_id (parser, *template_p, check_dependency_p, declarator_p, - /*optional_p=*/false); + /*optional_p=*/false, + decltype_p); /* Restore the SAVED_SCOPE for our caller. */ parser->scope = saved_scope; parser->object_scope = saved_object_scope; @@ -4925,7 +4925,8 @@ cp_parser_id_expression (cp_parser *parser, return cp_parser_unqualified_id (parser, template_keyword_p, /*check_dependency_p=*/true, declarator_p, - optional_p); + optional_p, + decltype_p); } /* Parse an unqualified-id. @@ -4955,7 +4956,8 @@ cp_parser_unqualified_id (cp_parser* parser, bool template_keyword_p, bool check_dependency_p, bool declarator_p, - bool optional_p) + bool optional_p, + bool decltype_p) { cp_token *token; @@ -5161,7 +5163,13 @@ cp_parser_unqualified_id (cp_parser* parser, && ! cp_parser_parse_definitely (parser)) { /* We couldn't find a type with this name, so just accept - it and check for a match at instantiation time. */ + it and check for a match at instantiation time. However + don't do that if we are parsing the immediate operand of + a decltype as an id-expression, because definitely the + production ~ class-name isn't ok and we want to look for + a complement expression (c++/65091). */ + if (decltype_p) + return error_mark_node; type_decl = cp_parser_identifier (parser); if (type_decl != error_mark_node) type_decl = build_nt (BIT_NOT_EXPR, type_decl); @@ -6709,9 +6717,7 @@ cp_parser_postfix_dot_deref_expression (cp_parser (parser, cp_parser_optional_template_keyword (parser), /*check_dependency_p=*/true, - &template_p, - /*declarator_p=*/false, - /*optional_p=*/false)); + &template_p)); /* In general, build a SCOPE_REF if the member name is qualified. However, if the name was not dependent and has already been resolved; there is no need to build the SCOPE_REF. For example; @@ -12250,7 +12256,8 @@ cp_parser_decltype_expr (cp_parser *parser, /*check_dependency_p=*/true, /*template_p=*/NULL, /*declarator_p=*/false, - /*optional_p=*/false); + /*optional_p=*/false, + /*decltype_p=*/true); if (!cp_parser_error_occurred (parser) && expr != error_mark_node) { @@ -13629,9 +13636,7 @@ cp_parser_type_parameter (cp_parser* parser, bool = cp_parser_id_expression (parser, /*template_keyword_p=*/false, /*check_dependency_p=*/true, - /*template_p=*/&is_template, - /*declarator_p=*/false, - /*optional_p=*/false); + /*template_p=*/&is_template); if (TREE_CODE (default_argument) == TYPE_DECL) /* If the id-expression was a template-id that refers to a template-class, we already have the declaration here, @@ -14273,9 +14278,7 @@ cp_parser_template_argument (cp_parser* parser) argument = cp_parser_id_expression (parser, /*template_keyword_p=*/false, /*check_dependency_p=*/true, - &template_p, - /*declarator_p=*/false, - /*optional_p=*/false); + &template_p); /* If the next token isn't a `,' or a `>', then this argument wasn't really finished. */ if (!cp_parser_next_token_ends_template_argument_p (parser)) @@ -16441,7 +16444,8 @@ cp_parser_using_declaration (cp_parser* parser, /*template_keyword_p=*/false, /*check_dependency_p=*/true, /*declarator_p=*/true, - /*optional_p=*/false); + /*optional_p=*/false, + /*decltype_p=*/false); if (access_declaration_p) { @@ -23253,7 +23257,8 @@ cp_parser_constructor_declarator_p (cp_parser *par /*template_keyword_p=*/false, /*check_dependency_p=*/false, /*declarator_p=*/true, - /*optional_p=*/false); + /*optional_p=*/false, + /*decltype_p=*/false); if (is_overloaded_fn (id)) id = DECL_NAME (get_first_fn (id)); if (!constructor_name_p (id, nested_name_specifier)) @@ -27823,10 +27828,7 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, token = cp_lexer_peek_token (parser->lexer); name = cp_parser_id_expression (parser, /*template_p=*/false, - /*check_dependency_p=*/true, - /*template_p=*/NULL, - /*declarator_p=*/false, - /*optional_p=*/false); + /*check_dependency_p=*/true); if (name == error_mark_node) goto skip_comma; @@ -28529,10 +28531,7 @@ cp_parser_omp_clause_reduction (cp_parser *parser, saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; parser->colon_corrects_to_scope_p = false; id = cp_parser_id_expression (parser, /*template_p=*/false, - /*check_dependency_p=*/true, - /*template_p=*/NULL, - /*declarator_p=*/false, - /*optional_p=*/false); + /*check_dependency_p=*/true); parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; if (identifier_p (id)) { @@ -32166,10 +32165,7 @@ cp_parser_omp_declare_reduction_exprs (tree fndecl { cp_parser_parse_tentatively (parser); tree fn_name = cp_parser_id_expression (parser, /*template_p=*/false, - /*check_dependency_p=*/true, - /*template_p=*/NULL, - /*declarator_p=*/false, - /*optional_p=*/false); + /*check_dependency_p=*/true); vec *args; if (fn_name == error_mark_node || cp_parser_error_occurred (parser) @@ -33347,8 +33343,7 @@ cp_parser_cilk_simd_linear (cp_parser *parser, tre break; } - tree var_name = cp_parser_id_expression (parser, false, true, NULL, - false, false); + tree var_name = cp_parser_id_expression (parser, false, true); tree decl = cp_parser_lookup_name_simple (parser, var_name, token->location); if (decl == error_mark_node) Index: testsuite/g++.dg/cpp0x/decltype63.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype63.C (revision 0) +++ testsuite/g++.dg/cpp0x/decltype63.C (working copy) @@ -0,0 +1,9 @@ +// PR c++/65091 +// { dg-do compile { target c++11 } } + +template +auto foo(T x) -> decltype(~x) +{ return ~x; } + +int bar() +{ return foo(10); }