On Fri, 25 Oct 2024, Patrick Palka wrote: > On Wed, 23 Oct 2024, Patrick Palka wrote: > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look > > OK for trunk? > > > > -- >8 -- > > > > This tree code was added as part of the initial Concepts TS > > implementation to support type-constraints introducing any kind > > of template-parameter, not just type template-parameters, e.g. > > > > template<int N> concept C = ...; > > template<template<class> class TT> concept D = ...; > > > > template<C T, D U> void f(); // T is an NTTP of type int, U is a TTP > > > > When resolving the type-constraint we would use WILDCARD_DECL as the > > dummy first argument during template argument coercion that is a valid > > argument for any kind of template parameter. > > > > But Concepts TS support has been removed, and C++20 type-constraints are > > restricted to only introduce type template-parameters, and so we don't > > need this catch-all WILDCARD_DECL anymore; we can instead use an auto > > as the dummy first argument. > > > > In passing introduce a helper for returning the prototype parameter > > (i.e. first template parameter) of a concept and use it. Also remove a > > redundant concept_definition_p overload. > > > > gcc/cp/ChangeLog: > > > > * constraint.cc (build_type_constraint): Use an auto as the > > first template argument. > > (finish_shorthand_constraint): Use concept_prototype_parameter. > > * cp-objcp-common.cc (cp_common_init_ts): Remove WILDCARD_DECL > > handling. > > * cp-tree.def (WILDCARD_DECL): Remove. > > * cp-tree.h (WILDCARD_PACK_P): Remove. > > (concept_definition_p): Remove redundant overload. > > (concept_prototype_parameter): Define. > > * error.cc (dump_decl) <case WILDCARD_DECL>: Remove. > > (dump_expr) <case WILDCARD_DECL>: Likewise. > > * parser.cc (cp_parser_placeholder_type_specifier): Check > > the prototype parameter earlier, before build_type_constraint. > > Use concept_prototype_parameter. > > * pt.cc (convert_wildcard_argument): Remove. > > (convert_template_argument): Remove WILDCARD_DECL handling. > > (coerce_template_parameter_pack): Likewise. > > (tsubst) <case TEMPLATE_TYPE_PARM>: Likewise. > > (type_dependent_expression_p): Likewise. > > (placeholder_type_constraint_dependent_p): Likewise. > > --- > > gcc/cp/constraint.cc | 6 ++---- > > gcc/cp/cp-objcp-common.cc | 1 - > > gcc/cp/cp-tree.def | 6 ------ > > gcc/cp/cp-tree.h | 27 ++++++++++++++------------- > > gcc/cp/error.cc | 5 ----- > > gcc/cp/parser.cc | 31 +++++++++++++++---------------- > > gcc/cp/pt.cc | 37 ++----------------------------------- > > 7 files changed, 33 insertions(+), 80 deletions(-) > > > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > > index 9394bea8835..d6a6ac03393 100644 > > --- a/gcc/cp/constraint.cc > > +++ b/gcc/cp/constraint.cc > > @@ -1154,9 +1154,8 @@ build_concept_id (tree expr) > > tree > > build_type_constraint (tree decl, tree args, tsubst_flags_t complain) > > { > > - tree wildcard = build_nt (WILDCARD_DECL); > > ++processing_template_decl; > > - tree check = build_concept_check (decl, wildcard, args, complain); > > + tree check = build_concept_check (decl, make_auto (), args, complain); > > On second thought I think it's better simply use the prototype parameter > as its own argument here so that we don't have to allocate a new auto > for each type-constraint we build. And it's more in the spirit with how > WILDCARD_DECL behaved. > > Like so:
Ping. > > -- >8 -- > > Subject: [PATCH v2] c++: remove WILDCARD_DECL > > gcc/cp/ChangeLog: > > * constraint.cc (build_type_constraint): Use the prototype > parameter as the first template argument. > (finish_shorthand_constraint): Use concept_prototype_parameter. > * cp-objcp-common.cc (cp_common_init_ts): Remove WILDCARD_DECL > handling. > * cp-tree.def (WILDCARD_DECL): Remove. > * cp-tree.h (WILDCARD_PACK_P): Remove. > (concept_definition_p): Remove redundant overload. > (concept_prototype_parameter): Define. > * error.cc (dump_decl) <case WILDCARD_DECL>: Remove. > (dump_expr) <case WILDCARD_DECL>: Likewise. > * parser.cc (cp_parser_placeholder_type_specifier): Check > the prototype parameter earlier, before build_type_constraint. > Use concept_prototype_parameter. > * pt.cc (convert_wildcard_argument): Remove. > (convert_template_argument): Remove WILDCARD_DECL handling. > (coerce_template_parameter_pack): Likewise. > (tsubst) <case TEMPLATE_TYPE_PARM>: Likewise. > (type_dependent_expression_p): Likewise. > (placeholder_type_constraint_dependent_p): Likewise. > --- > gcc/cp/constraint.cc | 7 +++---- > gcc/cp/cp-objcp-common.cc | 1 - > gcc/cp/cp-tree.def | 6 ------ > gcc/cp/cp-tree.h | 27 ++++++++++++++------------- > gcc/cp/error.cc | 5 ----- > gcc/cp/parser.cc | 31 +++++++++++++++---------------- > gcc/cp/pt.cc | 37 ++----------------------------------- > 7 files changed, 34 insertions(+), 80 deletions(-) > > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index 9394bea8835..8b826cb240e 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -1154,9 +1154,9 @@ build_concept_id (tree expr) > tree > build_type_constraint (tree decl, tree args, tsubst_flags_t complain) > { > - tree wildcard = build_nt (WILDCARD_DECL); > + tree proto = template_parm_to_arg (concept_prototype_parameter (decl)); > ++processing_template_decl; > - tree check = build_concept_check (decl, wildcard, args, complain); > + tree check = build_concept_check (decl, proto, args, complain); > --processing_template_decl; > return check; > } > @@ -1203,8 +1203,7 @@ finish_shorthand_constraint (tree decl, tree constr, > bool is_non_type) > { > tree id = PLACEHOLDER_TYPE_CONSTRAINTS (constr); > tree tmpl = TREE_OPERAND (id, 0); > - tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); > - proto = TREE_VALUE (TREE_VEC_ELT (parms, 0)); > + proto = concept_prototype_parameter (tmpl); > con = DECL_TEMPLATE_RESULT (tmpl); > args = TREE_OPERAND (id, 1); > } > diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc > index cd379514991..69eed72a5a2 100644 > --- a/gcc/cp/cp-objcp-common.cc > +++ b/gcc/cp/cp-objcp-common.cc > @@ -624,7 +624,6 @@ cp_common_init_ts (void) > > /* New decls. */ > MARK_TS_DECL_COMMON (TEMPLATE_DECL); > - MARK_TS_DECL_COMMON (WILDCARD_DECL); > > MARK_TS_DECL_NON_COMMON (USING_DECL); > > diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def > index 18f75108c7b..53511a6d8cc 100644 > --- a/gcc/cp/cp-tree.def > +++ b/gcc/cp/cp-tree.def > @@ -487,12 +487,6 @@ DEFTREECODE (OMP_DEPOBJ, "omp_depobj", tcc_statement, 2) > /* Used to represent information associated with constrained declarations. */ > DEFTREECODE (CONSTRAINT_INFO, "constraint_info", tcc_exceptional, 0) > > -/* A wildcard declaration is a placeholder for a template parameter > - used to resolve constrained-type-names in concepts. During > - resolution, the matching argument is saved as the TREE_TYPE > - of the wildcard. */ > -DEFTREECODE (WILDCARD_DECL, "wildcard_decl", tcc_declaration, 0) > - > /* A requires-expr has three operands. The first operand is > its parameter list (possibly NULL). The second is a list of > requirements, which are denoted by the _REQ* tree codes > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 6dcf32b178e..c25dafd5981 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -438,7 +438,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; > TINFO_HAS_ACCESS_ERRORS (in TEMPLATE_INFO) > SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR) > COMPOUND_REQ_NOEXCEPT_P (in COMPOUND_REQ) > - WILDCARD_PACK_P (in WILDCARD_DECL) > BLOCK_OUTER_CURLY_BRACE_P (in BLOCK) > FOLD_EXPR_MODIFY_P (*_FOLD_EXPR) > IF_STMT_CONSTEXPR_P (IF_STMT) > @@ -4042,9 +4041,6 @@ struct GTY(()) lang_decl { > #define PACK_EXPANSION_FORCE_EXTRA_ARGS_P(NODE) \ > TREE_LANG_FLAG_3 (PACK_EXPANSION_CHECK (NODE)) > > -/* True iff the wildcard can match a template parameter pack. */ > -#define WILDCARD_PACK_P(NODE) TREE_LANG_FLAG_0 (NODE) > - > /* Determine if this is an argument pack. */ > #define ARGUMENT_PACK_P(NODE) \ > (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK \ > @@ -8879,18 +8875,10 @@ variable_template_p (tree t) > > /* True iff T is a concept. */ > > -inline bool > -concept_definition_p (tree t) > -{ > - return TREE_CODE (STRIP_TEMPLATE (t)) == CONCEPT_DECL; > -} > - > -/* Same as above, but for const trees. */ > - > inline bool > concept_definition_p (const_tree t) > { > - return concept_definition_p (const_cast<tree> (t)); > + return TREE_CODE (STRIP_TEMPLATE (t)) == CONCEPT_DECL; > } > > /* True if t is an expression that checks a concept. */ > @@ -8903,6 +8891,19 @@ concept_check_p (const_tree t) > return false; > } > > +/* Return the prototype parameter of the concept T, > + i.e. its first declared template parameter. */ > + > +inline tree > +concept_prototype_parameter (const_tree t) > +{ > + gcc_checking_assert (concept_definition_p (t)); > + if (TREE_CODE (t) == CONCEPT_DECL) > + t = DECL_TI_TEMPLATE (t); > + tree parms = DECL_INNERMOST_TEMPLATE_PARMS (t); > + return TREE_VALUE (TREE_VEC_ELT (parms, 0)); > +} > + > /* Helpers for IMPLICIT_RVALUE_P to look through automatic dereference. */ > > inline bool > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > index 65f70c595cf..c5b256f3907 100644 > --- a/gcc/cp/error.cc > +++ b/gcc/cp/error.cc > @@ -1542,10 +1542,6 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags) > dump_simple_decl (pp, t, TREE_TYPE (t), flags); > break; > > - case WILDCARD_DECL: > - pp_string (pp, "<wildcard>"); > - break; > - > case TEMPLATE_ID_EXPR: > { > tree name = TREE_OPERAND (t, 0); > @@ -2376,7 +2372,6 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) > case TEMPLATE_DECL: > case NAMESPACE_DECL: > case LABEL_DECL: > - case WILDCARD_DECL: > case OVERLOAD: > case TYPE_DECL: > case USING_DECL: > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index 0bad62978dc..16e05acd7b8 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -20918,15 +20918,27 @@ cp_parser_placeholder_type_specifier (cp_parser > *parser, location_t loc, > /* A concept-name with no arguments can't be an expression. */ > tentative = false; > > + tree con = STRIP_TEMPLATE (tmpl); > + tree proto = concept_prototype_parameter (con); > tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error; > > + /* A type constraint constrains a contextually determined type or type > + parameter pack. */ > + if (TREE_CODE (proto) != TYPE_DECL) > + { > + if (!tentative) > + { > + auto_diagnostic_group d; > + error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > + } > + return error_mark_node; > + } > + > /* Get the concept and prototype parameter for the constraint. */ > tree check = build_type_constraint (tmpl, args, complain); > if (check == error_mark_node) > return error_mark_node; > - tree con = STRIP_TEMPLATE (tmpl); > - tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); > - tree proto = TREE_VALUE (TREE_VEC_ELT (parms, 0)); > > /* As per the standard, require auto or decltype(auto). */ > cp_token *placeholder = NULL, *close_paren = NULL; > @@ -20941,19 +20953,6 @@ cp_parser_placeholder_type_specifier (cp_parser > *parser, location_t loc, > close_paren = parens.require_close (parser); > } > > - /* A type constraint constrains a contextually determined type or type > - parameter pack. */ > - if (TREE_CODE (proto) != TYPE_DECL) > - { > - if (!tentative) > - { > - auto_diagnostic_group d; > - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > - } > - return error_mark_node; > - } > - > /* In a template parameter list, a type-parameter can be introduced > by type-constraints alone. */ > if (processing_template_parmlist && !placeholder) > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index ec4313090bd..9833b2bea5f 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -8539,16 +8539,6 @@ is_compatible_template_arg (tree parm, tree arg, tree > args) > return ttp_subsumes (parm_cons, arg); > } > > -// Convert a placeholder argument into a binding to the original > -// parameter. The original parameter is saved as the TREE_TYPE of > -// ARG. > -static inline tree > -convert_wildcard_argument (tree parm, tree arg) > -{ > - TREE_TYPE (arg) = parm; > - return arg; > -} > - > /* We can't fully resolve ARG given as a non-type template argument to TYPE, > because one of them is dependent. But we need to represent the > conversion for the benefit of cp_tree_equal. */ > @@ -8603,10 +8593,6 @@ convert_template_argument (tree parm, > if (parm == error_mark_node || error_operand_p (arg)) > return error_mark_node; > > - /* Trivially convert placeholders. */ > - if (TREE_CODE (arg) == WILDCARD_DECL) > - return convert_wildcard_argument (parm, arg); > - > if (arg == any_targ_node) > return arg; > > @@ -8988,16 +8974,6 @@ coerce_template_parameter_pack (tree parms, > > packed_args = make_tree_vec (TREE_VEC_LENGTH (packed_parms)); > } > - /* Check if we have a placeholder pack, which indicates we're > - in the context of a introduction list. In that case we want > - to match this pack to the single placeholder. */ > - else if (arg_idx < nargs > - && TREE_CODE (TREE_VEC_ELT (inner_args, arg_idx)) == WILDCARD_DECL > - && WILDCARD_PACK_P (TREE_VEC_ELT (inner_args, arg_idx))) > - { > - nargs = arg_idx + 1; > - packed_args = make_tree_vec (1); > - } > else > packed_args = make_tree_vec (nargs - arg_idx); > > @@ -16489,13 +16465,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, > tree in_decl) > { > int quals; > > - /* When building concept checks for the purpose of > - deducing placeholders, we can end up with wildcards > - where types are expected. Adjust this to the deduced > - value. */ > - if (TREE_CODE (arg) == WILDCARD_DECL) > - arg = TREE_TYPE (TREE_TYPE (arg)); > - > gcc_assert (TYPE_P (arg)); > > quals = cp_type_quals (arg) | cp_type_quals (t); > @@ -28559,8 +28528,7 @@ type_dependent_expression_p (tree expression) > > /* An unresolved name is always dependent. */ > if (identifier_p (expression) > - || TREE_CODE (expression) == USING_DECL > - || TREE_CODE (expression) == WILDCARD_DECL) > + || TREE_CODE (expression) == USING_DECL) > return true; > > /* A lambda-expression in template context is dependent. dependent_type_p > is > @@ -29603,8 +29571,7 @@ placeholder_type_constraint_dependent_p (tree t) > args = expand_template_argument_pack (args); > first = TREE_VEC_ELT (args, 0); > } > - gcc_checking_assert (TREE_CODE (first) == WILDCARD_DECL > - || is_auto (first)); > + gcc_checking_assert (is_auto (first)); > for (int i = 1; i < TREE_VEC_LENGTH (args); ++i) > if (dependent_template_arg_p (TREE_VEC_ELT (args, i))) > return true; > -- > 2.47.0.118.gfd3785337b > > > > --processing_template_decl; > > return check; > > } > > @@ -1203,8 +1202,7 @@ finish_shorthand_constraint (tree decl, tree constr, > > bool is_non_type) > > { > > tree id = PLACEHOLDER_TYPE_CONSTRAINTS (constr); > > tree tmpl = TREE_OPERAND (id, 0); > > - tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); > > - proto = TREE_VALUE (TREE_VEC_ELT (parms, 0)); > > + proto = concept_prototype_parameter (tmpl); > > con = DECL_TEMPLATE_RESULT (tmpl); > > args = TREE_OPERAND (id, 1); > > } > > diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc > > index cd379514991..69eed72a5a2 100644 > > --- a/gcc/cp/cp-objcp-common.cc > > +++ b/gcc/cp/cp-objcp-common.cc > > @@ -624,7 +624,6 @@ cp_common_init_ts (void) > > > > /* New decls. */ > > MARK_TS_DECL_COMMON (TEMPLATE_DECL); > > - MARK_TS_DECL_COMMON (WILDCARD_DECL); > > > > MARK_TS_DECL_NON_COMMON (USING_DECL); > > > > diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def > > index 18f75108c7b..53511a6d8cc 100644 > > --- a/gcc/cp/cp-tree.def > > +++ b/gcc/cp/cp-tree.def > > @@ -487,12 +487,6 @@ DEFTREECODE (OMP_DEPOBJ, "omp_depobj", tcc_statement, > > 2) > > /* Used to represent information associated with constrained declarations. > > */ > > DEFTREECODE (CONSTRAINT_INFO, "constraint_info", tcc_exceptional, 0) > > > > -/* A wildcard declaration is a placeholder for a template parameter > > - used to resolve constrained-type-names in concepts. During > > - resolution, the matching argument is saved as the TREE_TYPE > > - of the wildcard. */ > > -DEFTREECODE (WILDCARD_DECL, "wildcard_decl", tcc_declaration, 0) > > - > > /* A requires-expr has three operands. The first operand is > > its parameter list (possibly NULL). The second is a list of > > requirements, which are denoted by the _REQ* tree codes > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > > index 6dcf32b178e..c25dafd5981 100644 > > --- a/gcc/cp/cp-tree.h > > +++ b/gcc/cp/cp-tree.h > > @@ -438,7 +438,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX]; > > TINFO_HAS_ACCESS_ERRORS (in TEMPLATE_INFO) > > SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR) > > COMPOUND_REQ_NOEXCEPT_P (in COMPOUND_REQ) > > - WILDCARD_PACK_P (in WILDCARD_DECL) > > BLOCK_OUTER_CURLY_BRACE_P (in BLOCK) > > FOLD_EXPR_MODIFY_P (*_FOLD_EXPR) > > IF_STMT_CONSTEXPR_P (IF_STMT) > > @@ -4042,9 +4041,6 @@ struct GTY(()) lang_decl { > > #define PACK_EXPANSION_FORCE_EXTRA_ARGS_P(NODE) \ > > TREE_LANG_FLAG_3 (PACK_EXPANSION_CHECK (NODE)) > > > > -/* True iff the wildcard can match a template parameter pack. */ > > -#define WILDCARD_PACK_P(NODE) TREE_LANG_FLAG_0 (NODE) > > - > > /* Determine if this is an argument pack. */ > > #define ARGUMENT_PACK_P(NODE) \ > > (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK \ > > @@ -8879,18 +8875,10 @@ variable_template_p (tree t) > > > > /* True iff T is a concept. */ > > > > -inline bool > > -concept_definition_p (tree t) > > -{ > > - return TREE_CODE (STRIP_TEMPLATE (t)) == CONCEPT_DECL; > > -} > > - > > -/* Same as above, but for const trees. */ > > - > > inline bool > > concept_definition_p (const_tree t) > > { > > - return concept_definition_p (const_cast<tree> (t)); > > + return TREE_CODE (STRIP_TEMPLATE (t)) == CONCEPT_DECL; > > } > > > > /* True if t is an expression that checks a concept. */ > > @@ -8903,6 +8891,19 @@ concept_check_p (const_tree t) > > return false; > > } > > > > +/* Return the prototype parameter of the concept T, > > + i.e. its first declared template parameter. */ > > + > > +inline tree > > +concept_prototype_parameter (const_tree t) > > +{ > > + gcc_checking_assert (concept_definition_p (t)); > > + if (TREE_CODE (t) == CONCEPT_DECL) > > + t = DECL_TI_TEMPLATE (t); > > + tree parms = DECL_INNERMOST_TEMPLATE_PARMS (t); > > + return TREE_VALUE (TREE_VEC_ELT (parms, 0)); > > +} > > + > > /* Helpers for IMPLICIT_RVALUE_P to look through automatic dereference. */ > > > > inline bool > > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > > index 65f70c595cf..c5b256f3907 100644 > > --- a/gcc/cp/error.cc > > +++ b/gcc/cp/error.cc > > @@ -1542,10 +1542,6 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags) > > dump_simple_decl (pp, t, TREE_TYPE (t), flags); > > break; > > > > - case WILDCARD_DECL: > > - pp_string (pp, "<wildcard>"); > > - break; > > - > > case TEMPLATE_ID_EXPR: > > { > > tree name = TREE_OPERAND (t, 0); > > @@ -2376,7 +2372,6 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) > > case TEMPLATE_DECL: > > case NAMESPACE_DECL: > > case LABEL_DECL: > > - case WILDCARD_DECL: > > case OVERLOAD: > > case TYPE_DECL: > > case USING_DECL: > > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > > index 0bad62978dc..16e05acd7b8 100644 > > --- a/gcc/cp/parser.cc > > +++ b/gcc/cp/parser.cc > > @@ -20918,15 +20918,27 @@ cp_parser_placeholder_type_specifier (cp_parser > > *parser, location_t loc, > > /* A concept-name with no arguments can't be an expression. */ > > tentative = false; > > > > + tree con = STRIP_TEMPLATE (tmpl); > > + tree proto = concept_prototype_parameter (con); > > tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error; > > > > + /* A type constraint constrains a contextually determined type or type > > + parameter pack. */ > > + if (TREE_CODE (proto) != TYPE_DECL) > > + { > > + if (!tentative) > > + { > > + auto_diagnostic_group d; > > + error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > > + inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > > + } > > + return error_mark_node; > > + } > > + > > /* Get the concept and prototype parameter for the constraint. */ > > tree check = build_type_constraint (tmpl, args, complain); > > if (check == error_mark_node) > > return error_mark_node; > > - tree con = STRIP_TEMPLATE (tmpl); > > - tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); > > - tree proto = TREE_VALUE (TREE_VEC_ELT (parms, 0)); > > > > /* As per the standard, require auto or decltype(auto). */ > > cp_token *placeholder = NULL, *close_paren = NULL; > > @@ -20941,19 +20953,6 @@ cp_parser_placeholder_type_specifier (cp_parser > > *parser, location_t loc, > > close_paren = parens.require_close (parser); > > } > > > > - /* A type constraint constrains a contextually determined type or type > > - parameter pack. */ > > - if (TREE_CODE (proto) != TYPE_DECL) > > - { > > - if (!tentative) > > - { > > - auto_diagnostic_group d; > > - error_at (loc, "%qE does not constrain a type", DECL_NAME (con)); > > - inform (DECL_SOURCE_LOCATION (con), "concept defined here"); > > - } > > - return error_mark_node; > > - } > > - > > /* In a template parameter list, a type-parameter can be introduced > > by type-constraints alone. */ > > if (processing_template_parmlist && !placeholder) > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > index ec4313090bd..9833b2bea5f 100644 > > --- a/gcc/cp/pt.cc > > +++ b/gcc/cp/pt.cc > > @@ -8539,16 +8539,6 @@ is_compatible_template_arg (tree parm, tree arg, > > tree args) > > return ttp_subsumes (parm_cons, arg); > > } > > > > -// Convert a placeholder argument into a binding to the original > > -// parameter. The original parameter is saved as the TREE_TYPE of > > -// ARG. > > -static inline tree > > -convert_wildcard_argument (tree parm, tree arg) > > -{ > > - TREE_TYPE (arg) = parm; > > - return arg; > > -} > > - > > /* We can't fully resolve ARG given as a non-type template argument to > > TYPE, > > because one of them is dependent. But we need to represent the > > conversion for the benefit of cp_tree_equal. */ > > @@ -8603,10 +8593,6 @@ convert_template_argument (tree parm, > > if (parm == error_mark_node || error_operand_p (arg)) > > return error_mark_node; > > > > - /* Trivially convert placeholders. */ > > - if (TREE_CODE (arg) == WILDCARD_DECL) > > - return convert_wildcard_argument (parm, arg); > > - > > if (arg == any_targ_node) > > return arg; > > > > @@ -8988,16 +8974,6 @@ coerce_template_parameter_pack (tree parms, > > > > packed_args = make_tree_vec (TREE_VEC_LENGTH (packed_parms)); > > } > > - /* Check if we have a placeholder pack, which indicates we're > > - in the context of a introduction list. In that case we want > > - to match this pack to the single placeholder. */ > > - else if (arg_idx < nargs > > - && TREE_CODE (TREE_VEC_ELT (inner_args, arg_idx)) == > > WILDCARD_DECL > > - && WILDCARD_PACK_P (TREE_VEC_ELT (inner_args, arg_idx))) > > - { > > - nargs = arg_idx + 1; > > - packed_args = make_tree_vec (1); > > - } > > else > > packed_args = make_tree_vec (nargs - arg_idx); > > > > @@ -16489,13 +16465,6 @@ tsubst (tree t, tree args, tsubst_flags_t > > complain, tree in_decl) > > { > > int quals; > > > > - /* When building concept checks for the purpose of > > - deducing placeholders, we can end up with wildcards > > - where types are expected. Adjust this to the deduced > > - value. */ > > - if (TREE_CODE (arg) == WILDCARD_DECL) > > - arg = TREE_TYPE (TREE_TYPE (arg)); > > - > > gcc_assert (TYPE_P (arg)); > > > > quals = cp_type_quals (arg) | cp_type_quals (t); > > @@ -28559,8 +28528,7 @@ type_dependent_expression_p (tree expression) > > > > /* An unresolved name is always dependent. */ > > if (identifier_p (expression) > > - || TREE_CODE (expression) == USING_DECL > > - || TREE_CODE (expression) == WILDCARD_DECL) > > + || TREE_CODE (expression) == USING_DECL) > > return true; > > > > /* A lambda-expression in template context is dependent. > > dependent_type_p is > > @@ -29603,8 +29571,7 @@ placeholder_type_constraint_dependent_p (tree t) > > args = expand_template_argument_pack (args); > > first = TREE_VEC_ELT (args, 0); > > } > > - gcc_checking_assert (TREE_CODE (first) == WILDCARD_DECL > > - || is_auto (first)); > > + gcc_checking_assert (is_auto (first)); > > for (int i = 1; i < TREE_VEC_LENGTH (args); ++i) > > if (dependent_template_arg_p (TREE_VEC_ELT (args, i))) > > return true; > > -- > > 2.47.0.118.gfd3785337b > > > > >