From patchwork Mon Mar 6 14:44:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 735809 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 3vcMyM661Xz9sNV for ; Tue, 7 Mar 2017 01:44:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="eGF005vd"; 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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:content-type; q=dns; s=default; b=Smnj8OxbvsaPkpx7Sz laW3D0q1L/PkP1FBw27UaPOIYfahVokw19wm6ZSUbLixyfWQ/kB482Bl96JTueO6 X2q12Uqm+XDQM/UVSzCplXQPLgVDT/SRxOmq/k+z+EL7Log7XmvQP++ZHrTx0p+b Tn2+Us61HcngePXEC9gbpTlb4= 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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:content-type; s=default; bh=aOUsm4DveQ7lQsG9yBDajXh1 NDg=; b=eGF005vdRrfApwgKsVfm5IICRgYD8kw7SY6+CddnlHGXYzZjxJB1ZPCx KZz/qsrEmGH1FBuVsq4hV3/5NrLUTz35UKnCX1MLg+zfdMl1rjkWqiRSeTFj2IBU oMoinr0aYReCgyi2bfgvy3x5c5NkzF/+cxDfPH7xWr4O36ridJo= Received: (qmail 6540 invoked by alias); 6 Mar 2017 14:44:47 -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 6381 invoked by uid 89); 6 Mar 2017 14:44:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.2 spammy=TT, tt, sk:constru X-HELO: mail-ot0-f179.google.com Received: from mail-ot0-f179.google.com (HELO mail-ot0-f179.google.com) (74.125.82.179) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 06 Mar 2017 14:44:43 +0000 Received: by mail-ot0-f179.google.com with SMTP id x37so69345232ota.2 for ; Mon, 06 Mar 2017 06:44:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to; bh=3YC0RsOWLH9NWF9uZIi4P9xqW/dAvgIs+9PUPg8jtjQ=; b=N5w4q4N9OEfKqssr8rj2F00RsUtwYa+Yf8Bb9S8l2XmnUdi+4dAGyNXfln2sqZNvGj BUW75wb6IQnIjqk3j+4RwyVhN4mIRMwvVbmdLX6cKq6QIbNNqBTsTx0XGhZTCZsWkMqk uQkyvPFrFTcgNrTR7c3xxM/yyPgGgR05KUFmA2xbIA9ptaubflrmytgAleDCcfeGwAJs UH49d/BmrBFV9wJRIyDeu+gd15ORqwXG5iIRRHvNDxOOsbOBJxVVMSPbYRLlXIkxW8fn YVSFe7Nf8fL1lb1gAuPo2r/NWqI/OeMisZ7apvEQcEq28+82Fl5o7Bw5Y93hljTfqXwt Wxvw== X-Gm-Message-State: AMke39nZa+kD0zRwMuTMqnfBwP/7nReJoI1rFg2RDkiYFGP9Lf33AV/q7LxPYtLvphJQYvkG585FgShjahV5QMsv X-Received: by 10.157.57.228 with SMTP id y91mr9296581otb.33.1488811481681; Mon, 06 Mar 2017 06:44:41 -0800 (PST) MIME-Version: 1.0 Received: by 10.182.187.8 with HTTP; Mon, 6 Mar 2017 06:44:20 -0800 (PST) In-Reply-To: References: From: Jason Merrill Date: Mon, 6 Mar 2017 04:44:20 -1000 Message-ID: Subject: Re: C++ PATCH for C++17 class template argument deduction issues To: gcc-patches List X-IsSubscribed: yes On Thu, Mar 2, 2017 at 3:26 PM, Jason Merrill wrote: > On Wed, Mar 1, 2017 at 3:58 PM, Jason Merrill wrote: >> On Tue, Feb 28, 2017 at 1:56 PM, Jason Merrill wrote: >>> This patch implements some proposed resolutions to open issues with >>> C++17 class template argument deduction. > > This patch handles the issues of references to members of the class > template differently, by also allowing explicit guides to refer to > them: The committee didn't like this direction, so I'm reverting it. commit 522ce181ad77238b7e314377bf21f45579e7b6e8 Author: Jason Merrill Date: Sat Mar 4 13:18:47 2017 -1000 Revert "Allow deduction guides to look into primary template." * cp-tree.h, parser.c, pt.c, search.c: Revert. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 7583672..68f2722 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1272,7 +1272,6 @@ struct GTY(()) saved_scope { vec *lang_base; tree lang_name; tree template_parms; - tree deduction_guide_type; cp_binding_level *x_previous_class_level; tree x_saved_tree; @@ -5423,9 +5422,6 @@ struct cp_decl_specifier_seq { BOOL_BITFIELD gnu_thread_keyword_p : 1; /* True iff the type is a decltype. */ BOOL_BITFIELD decltype_p : 1; - /* True iff the declaration declares a constructor or C++17 deduction - guide. */ - BOOL_BITFIELD constructor_p : 1; }; /* The various kinds of declarators. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index fbe864f..e684870 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13313,8 +13313,6 @@ cp_parser_decl_specifier_seq (cp_parser* parser, && constructor_possible_p && (cp_parser_constructor_declarator_p (parser, decl_spec_seq_has_spec_p (decl_specs, ds_friend)))); - if (constructor_p) - decl_specs->constructor_p = true; /* If we don't have a DECL_SPEC yet, then we must be looking at a type-specifier. */ @@ -19012,7 +19010,7 @@ cp_parser_init_declarator (cp_parser* parser, enum cpp_ttype initialization_kind; bool is_direct_init = false; bool is_non_constant_init; - int ctor_dtor_or_conv_p = decl_specifiers->constructor_p ? -1 : 0; + int ctor_dtor_or_conv_p; bool friend_p = cp_parser_friend_p (decl_specifiers); tree pushed_scope = NULL_TREE; bool range_for_decl_p = false; @@ -19050,9 +19048,6 @@ cp_parser_init_declarator (cp_parser* parser, parser->default_arg_ok_p = saved_default_arg_ok_p; - if (cxx_dialect >= cxx1z) - scope_chain->deduction_guide_type = NULL_TREE; - /* If the DECLARATOR was erroneous, there's no need to go further. */ if (declarator == cp_error_declarator) @@ -19100,6 +19095,25 @@ cp_parser_init_declarator (cp_parser* parser, if (function_declarator_p (declarator)) { + /* Handle C++17 deduction guides. */ + if (!decl_specifiers->type + && ctor_dtor_or_conv_p <= 0 + && cxx_dialect >= cxx1z) + { + cp_declarator *id = get_id_declarator (declarator); + tree name = id->u.id.unqualified_name; + parser->scope = id->u.id.qualifying_scope; + tree tmpl = cp_parser_lookup_name_simple (parser, name, id->id_loc); + if (tmpl + && (DECL_CLASS_TEMPLATE_P (tmpl) + || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))) + { + id->u.id.unqualified_name = dguide_name (tmpl); + id->u.id.sfk = sfk_deduction_guide; + ctor_dtor_or_conv_p = 1; + } + } + /* Check to see if the token indicates the start of a function-definition. */ if (cp_parser_token_starts_function_definition_p (token)) @@ -19418,10 +19432,8 @@ cp_parser_init_declarator (cp_parser* parser, If CTOR_DTOR_OR_CONV_P is not NULL, *CTOR_DTOR_OR_CONV_P is used to detect constructors, destructors, deduction guides, or conversion operators. - The caller should set it before the call, to -1 if parsing the - decl-specifier-seq determined that we're declaring a constructor or - deduction guide, or 0 otherwise. This function sets it to -1 if the - declarator is a name, and +1 if it is a function. Usually you just want to + It is set to -1 if the declarator is a name, and +1 if it is a + function. Otherwise it is set to zero. Usually you just want to test for >0, but internally the negative value is used. (The reason for CTOR_DTOR_OR_CONV_P is that a declaration must have @@ -19452,6 +19464,11 @@ cp_parser_declarator (cp_parser* parser, tree class_type; tree gnu_attributes = NULL_TREE, std_attributes = NULL_TREE; + /* Assume this is not a constructor, destructor, or type-conversion + operator. */ + if (ctor_dtor_or_conv_p) + *ctor_dtor_or_conv_p = 0; + if (cp_parser_allow_gnu_extensions_p (parser)) gnu_attributes = cp_parser_gnu_attributes_opt (parser); @@ -19749,6 +19766,9 @@ cp_parser_direct_declarator (cp_parser* parser, /* Parse an array-declarator. */ tree bounds, attrs; + if (ctor_dtor_or_conv_p) + *ctor_dtor_or_conv_p = 0; + first = false; parser->default_arg_ok_p = false; parser->in_declarator_p = true; @@ -20003,34 +20023,6 @@ cp_parser_direct_declarator (cp_parser* parser, *ctor_dtor_or_conv_p = -1; } } - - if (cxx_dialect >= cxx1z - && sfk == sfk_none - && ctor_dtor_or_conv_p - && *ctor_dtor_or_conv_p == -1) - { - /* If *ctor_dtor_or_conv_p is set and we aren't declaring a - constructor, we must be declaring a deduction guide. */ - tree tmpl; - if (qualifying_scope) - tmpl = (lookup_qualified_name - (qualifying_scope, unqualified_name, - /*prefer_type*/false, /*complain*/true)); - else - tmpl = lookup_name (unqualified_name); - if (tmpl - && (DECL_CLASS_TEMPLATE_P (tmpl) - || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))) - { - unqualified_name = dguide_name (tmpl); - scope_chain->deduction_guide_type - = TREE_TYPE (unqualified_name); - sfk = sfk_deduction_guide; - } - else - gcc_checking_assert (false); - } - declarator = make_id_declarator (qualifying_scope, unqualified_name, sfk); @@ -23259,7 +23251,7 @@ cp_parser_member_declaration (cp_parser* parser) cp_declarator *declarator; tree initializer; tree asm_specification; - int ctor_dtor_or_conv_p = decl_specifiers.constructor_p ? -1 : 0; + int ctor_dtor_or_conv_p; /* Parse the declarator. */ declarator @@ -28342,7 +28334,7 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi) declarator. */ do { - int ctor_dtor_or_conv_p = 0; + int ctor_dtor_or_conv_p; cp_lexer_consume_token (parser->lexer); cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED, &ctor_dtor_or_conv_p, @@ -29663,7 +29655,7 @@ cp_parser_objc_class_ivars (cp_parser* parser) { tree width = NULL_TREE, attributes, first_attribute, decl; cp_declarator *declarator = NULL; - int ctor_dtor_or_conv_p = 0; + int ctor_dtor_or_conv_p; /* Check for a (possibly unnamed) bitfield declaration. */ token = cp_lexer_peek_token (parser->lexer); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 13293eb..416f132 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -14641,6 +14641,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) have to substitute this with one having context `D'. */ tree context = tsubst (DECL_CONTEXT (t), args, complain, in_decl); + if (dependent_scope_p (context)) + { + /* When rewriting a constructor into a deduction guide, a + non-dependent name can become dependent, so memtmpl + becomes context::template memtmpl. */ + tree type = tsubst (TREE_TYPE (t), args, complain, in_decl); + return build_qualified_name (type, context, DECL_NAME (t), + /*template*/true); + } return lookup_field (context, DECL_NAME(t), 0, false); } else @@ -16624,6 +16633,14 @@ tsubst_copy_and_build (tree t, if (targs == error_mark_node) return error_mark_node; + if (TREE_CODE (templ) == SCOPE_REF) + { + tree name = TREE_OPERAND (templ, 1); + tree tid = lookup_template_function (name, targs); + TREE_OPERAND (templ, 1) = tid; + return templ; + } + if (variable_template_p (templ)) RETURN (lookup_and_finish_template_variable (templ, targs, complain)); @@ -23459,9 +23476,6 @@ bool dependent_scope_p (tree scope) { return (scope && TYPE_P (scope) && dependent_type_p (scope) - && !(cxx_dialect >= cxx1z - && scope_chain->deduction_guide_type - && same_type_p (scope, scope_chain->deduction_guide_type)) && !currently_open_class (scope)); } @@ -25012,7 +25026,6 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain) if (outer_args) ctor = tsubst (ctor, outer_args, complain, ctor); type = DECL_CONTEXT (ctor); - scope_chain->deduction_guide_type = type; tree fn_tmpl; if (TREE_CODE (ctor) == TEMPLATE_DECL) { @@ -25105,7 +25118,6 @@ build_deduction_guide (tree ctor, tree outer_args, tsubst_flags_t complain) current_template_parms = save_parms; --processing_template_decl; } - scope_chain->deduction_guide_type = NULL_TREE; } if (!memtmpl) diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 6eb4124..09c1b4e 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1279,13 +1279,6 @@ lookup_member (tree xbasetype, tree name, int protect, bool want_type, if (tree t = currently_open_class (type)) type = t; - /* Declaration of a deduction guide can look inside the primary class - template; replace a compatible type with the real one. */ - if (cxx_dialect >= cxx1z - && scope_chain->deduction_guide_type - && same_type_p (type, scope_chain->deduction_guide_type)) - type = scope_chain->deduction_guide_type; - if (!basetype_path) basetype_path = TYPE_BINFO (type); diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction37.C b/gcc/testsuite/g++.dg/cpp1z/class-deduction37.C deleted file mode 100644 index ee21d14..0000000 --- a/gcc/testsuite/g++.dg/cpp1z/class-deduction37.C +++ /dev/null @@ -1,16 +0,0 @@ -// { dg-options -std=c++1z } - -template struct A -{ - using value_t = T; - A(value_t); -}; - -template -A(typename A::value_t) -> A; - -template struct same; -template struct same {}; - -A a(42); -same> s1;