From 90d9a8e6ef72bd85839fb092605aa6d945616178 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 6 Mar 2017 09:44:44 -0500 Subject: [PATCH] Revert "Allow deduction guides to look into primary template." * cp-tree.h, parser.c, pt.c, search.c: Revert. From-SVN: r245924 --- gcc/cp/ChangeLog | 5 ++ gcc/cp/cp-tree.h | 4 - gcc/cp/parser.c | 74 +++++++++---------- gcc/cp/pt.c | 22 ++++-- gcc/cp/search.c | 7 -- .../g++.dg/cpp1z/class-deduction37.C | 16 ---- 6 files changed, 55 insertions(+), 73 deletions(-) delete mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction37.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3d7eae90a27..fc9757b294b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2017-03-06 Jason Merrill + + Revert "Allow deduction guides to look into primary template." + * cp-tree.h, parser.c, pt.c, search.c: Revert. + 2017-03-05 Paolo Carlini PR c++/70266 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 75836727d80..68f2722d6da 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 fbe864f685a..e6848701150 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 13293ebd557..416f1323f4f 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 6eb41243814..09c1b4e6456 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 ee21d147fd6..00000000000 --- 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; -- 2.30.2