On Fri, 2 Aug 2024, Marek Polacek wrote: > Bootstrapped/regtested on x86_64-pc-linux-gnu. Comments? > > -- >8 -- > This patch removes vestigial Concepts TS code as discussed in > <https://gcc.gnu.org/pipermail/gcc-patches/2024-July/657937.html>.
Yay! FWIW I think we can also remove the concept_check_p checks in cxx_eval_call_expression cxx_eval_outermost_constant_expr cp_genericize_r <case CALL_EXPR> check_noexcept_r And perhaps we could rename *concept_check* to *concept_id* throughout to match the standard terminology. > > In particular, it removes code related to function/variable concepts. > That includes variable_concept_p and function_concept_p, which then > cascades into removing DECL_DECLARED_CONCEPT_P etc. So I think we > no longer need to say "standard concept" since there are no non-standard > ones anymore. > > I've added two new errors saying that "variable/function concepts are > no longer supported". > > gcc/cp/ChangeLog: > > * constexpr.cc (cxx_eval_constant_expression): Don't call > unpack_concept_check. Add a concept_check_p assert. Remove > function_concept_p code. > * constraint.cc (check_constraint_atom): Remove function concepts code. > (unpack_concept_check): Remove. > (get_concept_check_template): Remove Concepts TS code. > (resolve_function_concept_overload): Remove. > (resolve_function_concept_check): Remove. > (resolve_concept_check): Remove Concepts TS code. > (get_returned_expression): Remove. > (get_variable_initializer): Remove. > (get_concept_definition): Remove Concepts TS code. > (normalize_concept_check): Likewise. > (build_function_check): Remove. > (build_variable_check): Remove. > (build_standard_check): Use concept_definition_p instead of > standard_concept_p. > (build_concept_check): Remove variable_concept_p/function_concept_p > code. > (build_concept_id): Simplify. > (build_type_constraint): Likewise. > (placeholder_extract_concept_and_args): Likewise. > (satisfy_nondeclaration_constraints): Likewise. > (check_function_concept): Remove. > (get_constraint_error_location): Remove Concepts TS code. > * cp-tree.h (DECL_DECLARED_CONCEPT_P): Remove. > (check_function_concept): Remove. > (unpack_concept_check): Remove. > (standard_concept_p): Remove. > (variable_concept_p): Remove. > (function_concept_p): Remove. > (concept_definition_p): Simplify. > (concept_check_p): Don't check for CALL_EXPR. > * decl.cc (check_concept_refinement): Remove. > (duplicate_decls): Remove check_concept_refinement code. > (is_concept_var): Remove. > (cp_finish_decl): Remove is_concept_var. > (check_concept_fn): Remove. > (grokfndecl): Give an error about function concepts not being supported > anymore. Remove unused code. > (grokvardecl): Give an error about variable concepts not being > supported anymore. > (finish_function): Remove DECL_DECLARED_CONCEPT_P code. > * decl2.cc (min_vis_expr_r): Use concept_definition_p instead of > standard_concept_p. > (maybe_instantiate_decl): Remove DECL_DECLARED_CONCEPT_P check. > (mark_used): Likewise. > * error.cc (dump_simple_decl): Use concept_definition_p instead of > standard_concept_p. > (dump_function_decl): Remove DECL_DECLARED_CONCEPT_P code. > (print_concept_check_info): Don't call unpack_concept_check. > * mangle.cc (write_type_constraint): Likewise. > * parser.cc (cp_parser_nested_name_specifier_opt): Remove > function_concept_p code. Only check concept_definition_p, not > variable_concept_p/standard_concept_p. > (add_debug_begin_stmt): Remove DECL_DECLARED_CONCEPT_P code. > (cp_parser_template_declaration_after_parameters): Remove a stale > comment. > * pt.cc (check_explicit_specialization): Remove > DECL_DECLARED_CONCEPT_P code. > (process_partial_specialization): Remove variable_concept_p code. > (lookup_template_variable): Likewise. > (tsubst_expr) <case CALL_EXPR>: Remove Concepts TS code and simplify. > (do_decl_instantiation): Remove DECL_DECLARED_CONCEPT_P code. > (instantiate_decl): Likewise. > (placeholder_type_constraint_dependent_p): Don't call > unpack_concept_check. Add a concept_check_p assert. > (convert_generic_types_to_packs): Likewise. > * semantics.cc (finish_call_expr): Remove Concepts TS code and simplify. > > gcc/testsuite/ChangeLog: > > * g++.dg/concepts/decl-diagnose.C: Adjust dg-error. > * g++.dg/concepts/fn-concept2.C: Likewise. > * g++.dg/concepts/pr71128.C: Likewise. > * g++.dg/concepts/var-concept6.C: Likewise. > * g++.dg/cpp2a/concepts.C: Likewise. > --- > gcc/cp/constexpr.cc | 13 +- > gcc/cp/constraint.cc | 346 +----------------- > gcc/cp/cp-tree.h | 71 +--- > gcc/cp/decl.cc | 118 +----- > gcc/cp/decl2.cc | 4 +- > gcc/cp/error.cc | 10 +- > gcc/cp/mangle.cc | 4 +- > gcc/cp/parser.cc | 16 +- > gcc/cp/pt.cc | 60 +-- > gcc/cp/semantics.cc | 17 +- > gcc/testsuite/g++.dg/concepts/decl-diagnose.C | 8 +- > gcc/testsuite/g++.dg/concepts/fn-concept2.C | 4 +- > gcc/testsuite/g++.dg/concepts/pr71128.C | 8 +- > gcc/testsuite/g++.dg/concepts/var-concept6.C | 2 +- > gcc/testsuite/g++.dg/cpp2a/concepts.C | 4 +- > 15 files changed, 65 insertions(+), 620 deletions(-) > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > index 8277b3b79ba..b079be1b3d5 100644 > --- a/gcc/cp/constexpr.cc > +++ b/gcc/cp/constexpr.cc > @@ -8508,20 +8508,11 @@ cxx_eval_constant_expression (const constexpr_ctx > *ctx, tree t, > { > /* We can evaluate template-id that refers to a concept only if > the template arguments are non-dependent. */ > - tree id = unpack_concept_check (t); > - tree tmpl = TREE_OPERAND (id, 0); > + gcc_assert (concept_check_p (t)); > + tree tmpl = TREE_OPERAND (t, 0); > if (!concept_definition_p (tmpl)) > internal_error ("unexpected template-id %qE", t); > > - if (function_concept_p (tmpl)) > - { > - if (!ctx->quiet) > - error_at (cp_expr_loc_or_input_loc (t), > - "function concept must be called"); > - r = error_mark_node; > - break; > - } > - > if (!value_dependent_expression_p (t) > && !uid_sensitive_constexpr_evaluation_p ()) > r = evaluate_concept_check (t); > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index 853ea8c4b93..2da482cc93d 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -167,19 +167,6 @@ check_constraint_atom (cp_expr expr) > return false; > } > > - /* Check that we're using function concepts correctly. */ > - if (concept_check_p (expr)) > - { > - tree id = unpack_concept_check (expr); > - tree tmpl = TREE_OPERAND (id, 0); > - if (OVL_P (tmpl) && TREE_CODE (expr) == TEMPLATE_ID_EXPR) > - { > - error_at (EXPR_LOC_OR_LOC (expr, input_location), > - "function concept must be called"); > - return false; > - } > - } > - > return true; > } > > @@ -245,32 +232,13 @@ combine_constraint_expressions (tree lhs, tree rhs) > return finish_constraint_and_expr (UNKNOWN_LOCATION, lhs, rhs); > } > > -/* Extract the template-id from a concept check. For standard and variable > - checks, this is simply T. For function concept checks, this is the > - called function. */ > - > -tree > -unpack_concept_check (tree t) > -{ > - gcc_assert (concept_check_p (t)); > - > - if (TREE_CODE (t) == CALL_EXPR) > - t = CALL_EXPR_FN (t); > - > - gcc_assert (TREE_CODE (t) == TEMPLATE_ID_EXPR); > - return t; > -} > - > /* Extract the TEMPLATE_DECL from a concept check. */ > > tree > get_concept_check_template (tree t) > { > - tree id = unpack_concept_check (t); > - tree tmpl = TREE_OPERAND (id, 0); > - if (OVL_P (tmpl)) > - tmpl = OVL_FIRST (tmpl); > - return tmpl; > + gcc_assert (concept_check_p (t)); > + return TREE_OPERAND (t, 0); > } > > /*--------------------------------------------------------------------------- > @@ -285,101 +253,6 @@ get_concept_check_template (tree t) > matched declaration, and whose purpose contains the coerced template > arguments that can be substituted into the call. */ > > -/* Given an overload set OVL, try to find a unique definition that can be > - instantiated by the template arguments ARGS. > - > - This function is not called for arbitrary call expressions. In > particular, > - the call expression must be written with explicit template arguments > - and no function arguments. For example: > - > - f<T, U>() > - > - If a single match is found, this returns a TREE_LIST whose VALUE > - is the constraint function (not the template), and its PURPOSE is > - the complete set of arguments substituted into the parameter list. */ > - > -static tree > -resolve_function_concept_overload (tree ovl, tree args) > -{ > - int nerrs = 0; > - tree cands = NULL_TREE; > - for (lkp_iterator iter (ovl); iter; ++iter) > - { > - tree tmpl = *iter; > - if (TREE_CODE (tmpl) != TEMPLATE_DECL) > - continue; > - > - /* Don't try to deduce checks for non-concepts. We often end up trying > - to resolve constraints in functional casts as part of a > - postfix-expression. We can save time and headaches by not > - instantiating those declarations. > - > - NOTE: This masks a potential error, caused by instantiating > - non-deduced contexts using placeholder arguments. */ > - tree fn = DECL_TEMPLATE_RESULT (tmpl); > - if (DECL_ARGUMENTS (fn)) > - continue; > - if (!DECL_DECLARED_CONCEPT_P (fn)) > - continue; > - > - /* Remember the candidate if we can deduce a substitution. */ > - ++processing_template_decl; > - tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl)); > - if (tree subst = coerce_template_parms (parms, args, tmpl, tf_none)) > - { > - if (subst == error_mark_node) > - ++nerrs; > - else > - cands = tree_cons (subst, fn, cands); > - } > - --processing_template_decl; > - } > - > - if (!cands) > - /* We either had no candidates or failed deductions. */ > - return nerrs ? error_mark_node : NULL_TREE; > - else if (TREE_CHAIN (cands)) > - /* There are multiple candidates. */ > - return error_mark_node; > - > - return cands; > -} > - > -/* Determine if the call expression CALL is a constraint check, and > - return the concept declaration and arguments being checked. If CALL > - does not denote a constraint check, return NULL. */ > - > -tree > -resolve_function_concept_check (tree call) > -{ > - gcc_assert (TREE_CODE (call) == CALL_EXPR); > - > - /* A constraint check must be only a template-id expression. > - If it's a call to a base-link, its function(s) should be a > - template-id expression. If this is not a template-id, then > - it cannot be a concept-check. */ > - tree target = CALL_EXPR_FN (call); > - if (BASELINK_P (target)) > - target = BASELINK_FUNCTIONS (target); > - if (TREE_CODE (target) != TEMPLATE_ID_EXPR) > - return NULL_TREE; > - > - /* Get the overload set and template arguments and try to > - resolve the target. */ > - tree ovl = TREE_OPERAND (target, 0); > - > - /* This is a function call of a variable concept... ill-formed. */ > - if (TREE_CODE (ovl) == TEMPLATE_DECL) > - { > - error_at (location_of (call), > - "function call of variable concept %qE", call); > - return error_mark_node; > - } > - > - tree args = TREE_OPERAND (target, 1); > - return resolve_function_concept_overload (ovl, args); > -} > - > /* Returns a pair containing the checked concept and its associated > prototype parameter. The result is a TREE_LIST whose TREE_VALUE > is the concept (non-template) and whose TREE_PURPOSE contains > @@ -390,20 +263,8 @@ tree > resolve_concept_check (tree check) > { > gcc_assert (concept_check_p (check)); > - tree id = unpack_concept_check (check); > - tree tmpl = TREE_OPERAND (id, 0); > - > - /* If this is an overloaded function concept, perform overload > - resolution (this only happens when deducing prototype parameters > - and template introductions). */ > - if (TREE_CODE (tmpl) == OVERLOAD) > - { > - if (OVL_CHAIN (tmpl)) > - return resolve_function_concept_check (check); > - tmpl = OVL_FIRST (tmpl); > - } > - > - tree args = TREE_OPERAND (id, 1); > + tree tmpl = TREE_OPERAND (check, 0); > + tree args = TREE_OPERAND (check, 1); > tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); > ++processing_template_decl; > tree result = coerce_template_parms (parms, args, tmpl, tf_none); > @@ -466,55 +327,13 @@ finish_type_constraints (tree spec, tree args, > tsubst_flags_t complain) > Expansion of concept definitions > ---------------------------------------------------------------------------*/ > > -/* Returns the expression of a function concept. */ > - > -static tree > -get_returned_expression (tree fn) > -{ > - /* Extract the body of the function minus the return expression. */ > - tree body = DECL_SAVED_TREE (fn); > - if (!body) > - return error_mark_node; > - if (TREE_CODE (body) == BIND_EXPR) > - body = BIND_EXPR_BODY (body); > - if (TREE_CODE (body) != RETURN_EXPR) > - return error_mark_node; > - > - return TREE_OPERAND (body, 0); > -} > - > -/* Returns the initializer of a variable concept. */ > - > -static tree > -get_variable_initializer (tree var) > -{ > - tree init = DECL_INITIAL (var); > - if (!init) > - return error_mark_node; > - if (BRACE_ENCLOSED_INITIALIZER_P (init) > - && CONSTRUCTOR_NELTS (init) == 1) > - init = CONSTRUCTOR_ELT (init, 0)->value; > - return init; > -} > - > -/* Returns the definition of a variable or function concept. */ > +/* Returns the definition of a concept. */ > > static tree > get_concept_definition (tree decl) > { > - if (TREE_CODE (decl) == OVERLOAD) > - decl = OVL_FIRST (decl); > - > - if (TREE_CODE (decl) == TEMPLATE_DECL) > - decl = DECL_TEMPLATE_RESULT (decl); > - > - if (TREE_CODE (decl) == CONCEPT_DECL) > - return DECL_INITIAL (decl); > - if (VAR_P (decl)) > - return get_variable_initializer (decl); > - if (TREE_CODE (decl) == FUNCTION_DECL) > - return get_returned_expression (decl); > - gcc_unreachable (); > + gcc_assert (TREE_CODE (decl) == CONCEPT_DECL); > + return DECL_INITIAL (decl); > } > > /*--------------------------------------------------------------------------- > @@ -729,19 +548,9 @@ static GTY((deletable)) hash_table<norm_hasher> > *norm_cache; > static tree > normalize_concept_check (tree check, tree args, norm_info info) > { > - tree id = unpack_concept_check (check); > - tree tmpl = TREE_OPERAND (id, 0); > - tree targs = TREE_OPERAND (id, 1); > - > - /* A function concept is wrapped in an overload. */ > - if (TREE_CODE (tmpl) == OVERLOAD) > - { > - /* TODO: Can we diagnose this error during parsing? */ > - if (TREE_CODE (check) == TEMPLATE_ID_EXPR) > - error_at (EXPR_LOC_OR_LOC (check, input_location), > - "function concept must be called"); > - tmpl = OVL_FIRST (tmpl); > - } > + gcc_assert (concept_check_p (check)); > + tree tmpl = TREE_OPERAND (check, 0); > + tree targs = TREE_OPERAND (check, 1); > > /* Substitute through the arguments of the concept check. */ > if (args) > @@ -789,11 +598,7 @@ normalize_concept_check (tree check, tree args, > norm_info info) > > static GTY((deletable)) hash_table<atom_hasher> *atom_cache; > > -/* The normal form of an atom depends on the expression. The normal > - form of a function call to a function concept is a check constraint > - for that concept. The normal form of a reference to a variable > - concept is a check constraint for that concept. Otherwise, the > - constraint is a predicate constraint. */ > +/* The normal form of an atom is a predicate constraint. */ > > static tree > normalize_atom (tree t, tree args, norm_info info) > @@ -1378,77 +1183,13 @@ build_concept_check_arguments (tree arg, tree rest) > return args; > } > > -/* Builds an id-expression of the form `C<Args...>()` where C is a function > - concept. */ > - > -static tree > -build_function_check (tree tmpl, tree args, tsubst_flags_t /*complain*/) > -{ > - if (TREE_CODE (tmpl) == TEMPLATE_DECL) > - { > - /* If we just got a template, wrap it in an overload so it looks like > any > - other template-id. */ > - tmpl = ovl_make (tmpl); > - TREE_TYPE (tmpl) = boolean_type_node; > - } > - > - /* Perform function concept resolution now so we always have a single > - function of the overload set (even if we started with only one; the > - resolution function converts template arguments). Note that we still > - wrap this in an overload set so we don't upset other parts of the > - compiler that expect template-ids referring to function concepts > - to have an overload set. */ > - tree info = resolve_function_concept_overload (tmpl, args); > - if (info == error_mark_node) > - return error_mark_node; > - if (!info) > - { > - error ("no matching concepts for %qE", tmpl); > - return error_mark_node; > - } > - args = TREE_PURPOSE (info); > - tmpl = DECL_TI_TEMPLATE (TREE_VALUE (info)); > - > - /* Rebuild the singleton overload set; mark the type bool. */ > - tmpl = ovl_make (tmpl, NULL_TREE); > - TREE_TYPE (tmpl) = boolean_type_node; > - > - /* Build the id-expression around the overload set. */ > - tree id = build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args); > - > - /* Finally, build the call expression around the overload. */ > - ++processing_template_decl; > - vec<tree, va_gc> *fargs = make_tree_vector (); > - tree call = build_min_nt_call_vec (id, fargs); > - TREE_TYPE (call) = boolean_type_node; > - release_tree_vector (fargs); > - --processing_template_decl; > - > - return call; > -} > - > -/* Builds an id-expression of the form `C<Args...>` where C is a variable > - concept. */ > - > -static tree > -build_variable_check (tree tmpl, tree args, tsubst_flags_t complain) > -{ > - gcc_assert (variable_concept_p (tmpl)); > - gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); > - tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl)); > - args = coerce_template_parms (parms, args, tmpl, complain); > - if (args == error_mark_node) > - return error_mark_node; > - return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args); > -} > - > /* Builds an id-expression of the form `C<Args...>` where C is a standard > concept. */ > > static tree > build_standard_check (tree tmpl, tree args, tsubst_flags_t complain) > { > - gcc_assert (standard_concept_p (tmpl)); > + gcc_assert (concept_definition_p (tmpl)); > gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL); > if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl))) > warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE); > @@ -1475,12 +1216,8 @@ build_concept_check (tree decl, tree arg, tree rest, > tsubst_flags_t complain) > { > tree args = build_concept_check_arguments (arg, rest); > > - if (standard_concept_p (decl)) > + if (concept_definition_p (decl)) > return build_standard_check (decl, args, complain); > - if (variable_concept_p (decl)) > - return build_variable_check (decl, args, complain); > - if (function_concept_p (decl)) > - return build_function_check (decl, args, complain); > > return error_mark_node; > } > @@ -1490,10 +1227,7 @@ build_concept_check (tree decl, tree arg, tree rest, > tsubst_flags_t complain) > static tree > build_concept_id (tree decl, tree args) > { > - tree check = build_concept_check (decl, args, tf_warning_or_error); > - if (check == error_mark_node) > - return error_mark_node; > - return unpack_concept_check (check); > + return build_concept_check (decl, args, tf_warning_or_error); > } > > /* Build a template-id that can participate in a concept check, preserving > @@ -1521,9 +1255,7 @@ build_type_constraint (tree decl, tree args, > tsubst_flags_t complain) > ++processing_template_decl; > tree check = build_concept_check (decl, wildcard, args, complain); > --processing_template_decl; > - if (check == error_mark_node) > - return error_mark_node; > - return unpack_concept_check (check); > + return check; > } > > /* Returns a TYPE_DECL that contains sufficient information to > @@ -1621,10 +1353,7 @@ placeholder_extract_concept_and_args (tree t, tree > &tmpl, tree &args) > { > if (concept_check_p (t)) > { > - t = unpack_concept_check (t); > tmpl = TREE_OPERAND (t, 0); > - if (TREE_CODE (tmpl) == OVERLOAD) > - tmpl = OVL_FIRST (tmpl); > args = TREE_OPERAND (t, 1); > return; > } > @@ -2938,9 +2667,8 @@ satisfy_nondeclaration_constraints (tree t, tree args, > sat_info info) > if (concept_check_p (t)) > { > gcc_assert (!args); > - tree id = unpack_concept_check (t); > - args = TREE_OPERAND (id, 1); > - tree tmpl = get_concept_check_template (id); > + args = TREE_OPERAND (t, 1); > + tree tmpl = get_concept_check_template (t); > norm = normalize_concept_definition (tmpl, info.noisy ()); > } > else if (TREE_CODE (t) == NESTED_REQ) > @@ -3255,41 +2983,6 @@ finish_nested_requirement (location_t loc, tree expr) > return r; > } > > -/* Check that FN satisfies the structural requirements of a > - function concept definition. */ > -tree > -check_function_concept (tree fn) > -{ > - /* Check that the function is comprised of only a return statement. */ > - tree body = DECL_SAVED_TREE (fn); > - if (TREE_CODE (body) == BIND_EXPR) > - body = BIND_EXPR_BODY (body); > - > - /* Sometimes a function call results in the creation of clean up > - points. Allow these to be preserved in the body of the > - constraint, as we might actually need them for some constexpr > - evaluations. */ > - if (TREE_CODE (body) == CLEANUP_POINT_EXPR) > - body = TREE_OPERAND (body, 0); > - > - /* Check that the definition is written correctly. */ > - if (TREE_CODE (body) != RETURN_EXPR) > - { > - location_t loc = DECL_SOURCE_LOCATION (fn); > - if (TREE_CODE (body) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (body)) > - { > - if (seen_error ()) > - /* The definition was probably erroneous, not empty. */; > - else > - error_at (loc, "definition of concept %qD is empty", fn); > - } > - else > - error_at (loc, "definition of concept %qD has multiple statements", > fn); > - } > - > - return NULL_TREE; > -} > - > /*--------------------------------------------------------------------------- > Equivalence of constraints > ---------------------------------------------------------------------------*/ > @@ -3403,10 +3096,7 @@ get_constraint_error_location (tree t) > /* Otherwise, give the location as the defining concept. */ > else if (concept_check_p (src)) > { > - tree id = unpack_concept_check (src); > - tree tmpl = TREE_OPERAND (id, 0); > - if (OVL_P (tmpl)) > - tmpl = OVL_FIRST (tmpl); > + tree tmpl = TREE_OPERAND (src, 0); > return DECL_SOURCE_LOCATION (tmpl); > } > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 238d786b067..c92ff707e3f 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -3524,12 +3524,6 @@ struct GTY(()) lang_decl { > (retrofit_lang_decl (FUNCTION_DECL_CHECK (NODE)), \ > LANG_DECL_FN_CHECK (NODE)->immediate_fn_p = true) > > -// True if NODE was declared as 'concept'. The flag implies that the > -// declaration is constexpr, that the declaration cannot be specialized or > -// refined, and that the result type must be convertible to bool. > -#define DECL_DECLARED_CONCEPT_P(NODE) \ > - (DECL_LANG_SPECIFIC (NODE)->u.base.concept_p) > - > /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a > template function. */ > #define DECL_PRETTY_FUNCTION_P(NODE) \ > @@ -8582,7 +8576,6 @@ extern bool equivalent_placeholder_constraints (tree, > tree); > extern hashval_t iterative_hash_placeholder_constraint (tree, > hashval_t); > extern bool deduce_constrained_parameter (tree, tree&, tree&); > extern tree resolve_constraint_check (tree); > -extern tree check_function_concept (tree); > extern bool valid_requirements_p (tree); > extern tree finish_concept_name (tree); > extern tree finish_shorthand_constraint (tree, tree); > @@ -8605,7 +8598,6 @@ struct processing_constraint_expression_sentinel > > extern bool processing_constraint_expression_p (); > > -extern tree unpack_concept_check (tree); > extern tree get_concept_check_template (tree); > extern tree evaluate_concept_check (tree); > extern bool constraints_satisfied_p (tree, tree = NULL_TREE); > @@ -8867,69 +8859,12 @@ variable_template_p (tree t) > return false; > } > > -/* True iff T is a standard concept definition. This will return > - true for both the template and underlying declaration. */ > - > -inline bool > -standard_concept_p (tree t) > -{ > - if (TREE_CODE (t) == TEMPLATE_DECL) > - t = DECL_TEMPLATE_RESULT (t); > - return TREE_CODE (t) == CONCEPT_DECL; > -} > - > -/* True iff T is a variable concept definition. This will return > - true for both the template and the underlying declaration. */ > - > -inline bool > -variable_concept_p (tree t) > -{ > - if (TREE_CODE (t) == TEMPLATE_DECL) > - t = DECL_TEMPLATE_RESULT (t); > - return VAR_P (t) && DECL_DECLARED_CONCEPT_P (t); > -} > - > -/* True iff T is a function concept definition or an overload set > - containing multiple function concepts. This will return true for > - both the template and the underlying declaration. */ > - > -inline bool > -function_concept_p (tree t) > -{ > - if (TREE_CODE (t) == OVERLOAD) > - t = OVL_FIRST (t); > - if (TREE_CODE (t) == TEMPLATE_DECL) > - t = DECL_TEMPLATE_RESULT (t); > - return TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_CONCEPT_P (t); > -} > - > -/* True iff T is a standard, variable, or function concept. */ > +/* True iff T is a concept. */ > > inline bool > concept_definition_p (tree t) > { > - if (t == error_mark_node) > - return false; > - > - /* Adjust for function concept overloads. */ > - if (TREE_CODE (t) == OVERLOAD) > - t = OVL_FIRST (t); > - > - /* See through templates. */ > - if (TREE_CODE (t) == TEMPLATE_DECL) > - t = DECL_TEMPLATE_RESULT (t); > - > - /* The obvious and easy case. */ > - if (TREE_CODE (t) == CONCEPT_DECL) > - return true; > - > - /* Definitely not a concept. */ > - if (!VAR_OR_FUNCTION_DECL_P (t)) > - return false; > - if (!DECL_LANG_SPECIFIC (t)) > - return false; > - > - return DECL_DECLARED_CONCEPT_P (t); > + return TREE_CODE (STRIP_TEMPLATE (t)) == CONCEPT_DECL; > } > > /* Same as above, but for const trees. */ > @@ -8945,8 +8880,6 @@ concept_definition_p (const_tree t) > inline bool > concept_check_p (const_tree t) > { > - if (TREE_CODE (t) == CALL_EXPR) > - t = CALL_EXPR_FN (t); > if (t && TREE_CODE (t) == TEMPLATE_ID_EXPR) > return concept_definition_p (TREE_OPERAND (t, 0)); > return false; > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > index 687ae6937f5..04877087dc7 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -1467,36 +1467,6 @@ validate_constexpr_redeclaration (tree old_decl, tree > new_decl) > return true; > } > > -// If OLDDECL and NEWDECL are concept declarations with the same type > -// (i.e., and template parameters), but different requirements, > -// emit diagnostics and return true. Otherwise, return false. > -static inline bool > -check_concept_refinement (tree olddecl, tree newdecl) > -{ > - if (!DECL_DECLARED_CONCEPT_P (olddecl) || !DECL_DECLARED_CONCEPT_P > (newdecl)) > - return false; > - > - tree d1 = DECL_TEMPLATE_RESULT (olddecl); > - tree d2 = DECL_TEMPLATE_RESULT (newdecl); > - if (TREE_CODE (d1) != TREE_CODE (d2)) > - return false; > - > - tree t1 = TREE_TYPE (d1); > - tree t2 = TREE_TYPE (d2); > - if (TREE_CODE (d1) == FUNCTION_DECL) > - { > - if (compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)) > - && comp_template_parms (DECL_TEMPLATE_PARMS (olddecl), > - DECL_TEMPLATE_PARMS (newdecl)) > - && !equivalently_constrained (olddecl, newdecl)) > - { > - error ("cannot specialize concept %q#D", olddecl); > - return true; > - } > - } > - return false; > -} > - > /* DECL is a redeclaration of a function or function template. If > it does have default arguments issue a diagnostic. Note: this > function is used to enforce the requirements in C++11 8.3.6 about > @@ -1990,8 +1960,6 @@ duplicate_decls (tree newdecl, tree olddecl, bool > hiding, bool was_hidden) > return error_mark_node; > return NULL_TREE; > } > - else if (check_concept_refinement (olddecl, newdecl)) > - return error_mark_node; > return NULL_TREE; > } > if (TREE_CODE (newdecl) == FUNCTION_DECL) > @@ -8224,16 +8192,6 @@ value_dependent_init_p (tree init) > return false; > } > > -// Returns true if a DECL is VAR_DECL with the concept specifier. > -static inline bool > -is_concept_var (tree decl) > -{ > - return (VAR_P (decl) > - // Not all variables have DECL_LANG_SPECIFIC. > - && DECL_LANG_SPECIFIC (decl) > - && DECL_DECLARED_CONCEPT_P (decl)); > -} > - > /* A helper function to be called via walk_tree. If any label exists > under *TP, it is (going to be) forced. Set has_forced_label_in_static. > */ > > @@ -8751,11 +8709,6 @@ cp_finish_decl (tree decl, tree init, bool > init_const_expr_p, > > if (!VAR_P (decl) || type_dependent_p) > /* We can't do anything if the decl has dependent type. */; > - else if (!init && is_concept_var (decl)) > - { > - error ("variable concept has no initializer"); > - init = boolean_true_node; > - } > else if (init > && (init_const_expr_p || DECL_DECLARED_CONSTEXPR_P (decl)) > && !TYPE_REF_P (type) > @@ -10547,26 +10500,6 @@ check_static_quals (tree decl, cp_cv_quals quals) > decl); > } > > -// Check that FN takes no arguments and returns bool. > -static void > -check_concept_fn (tree fn) > -{ > - // A constraint is nullary. > - if (DECL_ARGUMENTS (fn)) > - error_at (DECL_SOURCE_LOCATION (fn), > - "concept %q#D declared with function parameters", fn); > - > - // The declared return type of the concept shall be bool, and > - // it shall not be deduced from it definition. > - tree type = TREE_TYPE (TREE_TYPE (fn)); > - if (is_auto (type)) > - error_at (DECL_SOURCE_LOCATION (fn), > - "concept %q#D declared with a deduced return type", fn); > - else if (type != boolean_type_node) > - error_at (DECL_SOURCE_LOCATION (fn), > - "concept %q#D with non-%<bool%> return type %qT", fn, type); > -} > - > /* Helper function. Replace the temporary this parameter injected > during cp_finish_omp_declare_simd with the real this parameter. */ > > @@ -10637,10 +10570,9 @@ grokfndecl (tree ctype, > /* Was the concept specifier present? */ > bool concept_p = inlinep & 4; > > - /* Concept declarations must have a corresponding definition. */ > - if (concept_p && !funcdef_flag) > + if (concept_p) > { > - error_at (location, "concept %qD has no definition", declarator); > + error_at (location, "function concepts are no longer supported"); > return NULL_TREE; > } > > @@ -10667,11 +10599,6 @@ grokfndecl (tree ctype, > tmpl_reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms); > } > tree ci = build_constraints (tmpl_reqs, decl_reqs); > - if (concept_p && ci) > - { > - error_at (location, "a function concept cannot be constrained"); > - ci = NULL_TREE; > - } > /* C++20 CA378: Remove non-templated constrained functions. */ > /* [temp.friend]/9 A non-template friend declaration with a > requires-clause shall be a definition. A friend function template with > @@ -10903,14 +10830,6 @@ grokfndecl (tree ctype, > SET_DECL_IMMEDIATE_FUNCTION_P (decl); > } > > - // If the concept declaration specifier was found, check > - // that the declaration satisfies the necessary requirements. > - if (concept_p) > - { > - DECL_DECLARED_CONCEPT_P (decl) = true; > - check_concept_fn (decl); > - } > - > DECL_EXTERNAL (decl) = 1; > if (TREE_CODE (type) == FUNCTION_TYPE) > { > @@ -11072,8 +10991,7 @@ grokfndecl (tree ctype, > decl = check_explicit_specialization (orig_declarator, decl, > template_count, > 2 * funcdef_flag + > - 4 * (friendp != 0) + > - 8 * concept_p, > + 4 * (friendp != 0), > *attrlist); > if (decl == error_mark_node) > return NULL_TREE; > @@ -11365,29 +11283,19 @@ grokvardecl (tree type, > "C language linkage"); > } > > - /* Check that the variable can be safely declared as a concept. > - Note that this also forbids explicit specializations. */ > + /* Check if a variable is being declared as a concept. */ > if (conceptp) > { > if (!processing_template_decl) > - { > - error_at (declspecs->locations[ds_concept], > - "a non-template variable cannot be %<concept%>"); > - return NULL_TREE; > - } > + error_at (declspecs->locations[ds_concept], > + "a non-template variable cannot be %<concept%>"); > else if (!at_namespace_scope_p ()) > - { > - error_at (declspecs->locations[ds_concept], > - "concept must be defined at namespace scope"); > - return NULL_TREE; > - } > + error_at (declspecs->locations[ds_concept], > + "concept must be defined at namespace scope"); > else > - DECL_DECLARED_CONCEPT_P (decl) = true; > - if (TEMPLATE_PARMS_CONSTRAINTS (current_template_parms)) > - { > - error_at (location, "a variable concept cannot be constrained"); > - TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = NULL_TREE; > - } > + error_at (declspecs->locations[ds_concept], > + "variable concepts are no longer supported"); > + return NULL_TREE; > } > else if (flag_concepts > && current_template_depth > template_class_depth (scope)) > @@ -18808,10 +18716,6 @@ finish_function (bool inline_p) > goto cleanup; > } > > - // If this is a concept, check that the definition is reasonable. > - if (DECL_DECLARED_CONCEPT_P (fndecl)) > - check_function_concept (fndecl); > - > if (flag_openmp) > if (tree attr = lookup_attribute ("omp declare variant base", > DECL_ATTRIBUTES (fndecl))) > diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc > index 6d674684931..695d5f8d790 100644 > --- a/gcc/cp/decl2.cc > +++ b/gcc/cp/decl2.cc > @@ -2723,7 +2723,7 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void > *data) > break; > > case TEMPLATE_DECL: > - if (DECL_ALIAS_TEMPLATE_P (t) || standard_concept_p (t)) > + if (DECL_ALIAS_TEMPLATE_P (t) || concept_definition_p (t)) > /* FIXME: We don't maintain TREE_PUBLIC / DECL_VISIBILITY for > alias templates so we can't trust it here (PR107906). Ditto > for concepts. */ > @@ -5687,7 +5687,6 @@ maybe_instantiate_decl (tree decl) > if (VAR_OR_FUNCTION_DECL_P (decl) > && DECL_LANG_SPECIFIC (decl) > && DECL_TEMPLATE_INFO (decl) > - && !DECL_DECLARED_CONCEPT_P (decl) > && !uses_template_parms (DECL_TI_ARGS (decl))) > { > /* Instantiating a function will result in garbage collection. We > @@ -6084,7 +6083,6 @@ mark_used (tree decl, tsubst_flags_t complain /* = > tf_warning_or_error */) > } > else if (VAR_OR_FUNCTION_DECL_P (decl) > && DECL_TEMPLATE_INFO (decl) > - && !DECL_DECLARED_CONCEPT_P (decl) > && (!DECL_EXPLICIT_INSTANTIATION (decl) > || always_instantiate_p (decl))) > /* If this is a function or variable that is an instance of some > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc > index d80bac822ba..aecbc4ff0d9 100644 > --- a/gcc/cp/error.cc > +++ b/gcc/cp/error.cc > @@ -1163,7 +1163,7 @@ dump_simple_decl (cxx_pretty_printer *pp, tree t, tree > type, int flags) > else if (VAR_P (t) && DECL_DECLARED_CONSTEXPR_P (t)) > pp_cxx_ws_string (pp, "constexpr"); > > - if (!standard_concept_p (t)) > + if (!concept_definition_p (t)) > dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME); > pp_maybe_space (pp); > } > @@ -1806,9 +1806,7 @@ dump_function_decl (cxx_pretty_printer *pp, tree t, int > flags) > > if (constexpr_p) > { > - if (DECL_DECLARED_CONCEPT_P (t)) > - pp_cxx_ws_string (pp, "concept"); > - else if (DECL_IMMEDIATE_FUNCTION_P (t)) > + if (DECL_IMMEDIATE_FUNCTION_P (t)) > pp_cxx_ws_string (pp, "consteval"); > else > pp_cxx_ws_string (pp, "constexpr"); > @@ -3952,8 +3950,8 @@ print_concept_check_info (diagnostic_context *context, > tree expr, tree map, tree > { > gcc_assert (concept_check_p (expr)); > > - tree id = unpack_concept_check (expr); > - tree tmpl = TREE_OPERAND (id, 0); > + tree tmpl = TREE_OPERAND (expr, 0); > + // ??? Can this go now that fn/var concepts have been removed? > if (OVL_P (tmpl)) > tmpl = OVL_FIRST (tmpl); > > diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc > index e7391220234..46dc6923add 100644 > --- a/gcc/cp/mangle.cc > +++ b/gcc/cp/mangle.cc > @@ -901,9 +901,9 @@ write_tparms_constraints (tree constraints) > static void > write_type_constraint (tree cnst) > { > - if (!cnst) return; > + if (!cnst) > + return; > > - cnst = unpack_concept_check (cnst); > gcc_checking_assert (TREE_CODE (cnst) == TEMPLATE_ID_EXPR); > > tree concept_decl = get_concept_check_template (cnst); > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index eb102dea829..f625b0a310c 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -7161,18 +7161,13 @@ cp_parser_nested_name_specifier_opt (cp_parser > *parser, > tree fns = get_fns (tid); > if (OVL_SINGLE_P (fns)) > tmpl = OVL_FIRST (fns); > - if (function_concept_p (fns)) > - error_at (token->location, "concept-id %qD " > - "in nested-name-specifier", tid); > - else > - error_at (token->location, "function template-id " > - "%qD in nested-name-specifier", tid); > + error_at (token->location, "function template-id " > + "%qD in nested-name-specifier", tid); > } > else > { > tmpl = TREE_OPERAND (tid, 0); > - if (variable_concept_p (tmpl) > - || standard_concept_p (tmpl)) > + if (concept_definition_p (tmpl)) > error_at (token->location, "concept-id %qD " > "in nested-name-specifier", tid); > else > @@ -12224,9 +12219,6 @@ add_debug_begin_stmt (location_t loc) > { > if (!MAY_HAVE_DEBUG_MARKER_STMTS) > return; > - if (DECL_DECLARED_CONCEPT_P (current_function_decl)) > - /* A concept is never expanded normally. */ > - return; > > tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node); > SET_EXPR_LOCATION (stmt, loc); > @@ -33087,8 +33079,6 @@ cp_parser_template_declaration_after_parameters > (cp_parser* parser, > else if (flag_concepts > && cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT) > && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)) > - /* -fconcept-ts 'concept bool' syntax is handled below, in > - cp_parser_single_declaration. */ > decl = cp_parser_concept_definition (parser); > else > { > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > index 77fa5907c3d..35a9c5619f9 100644 > --- a/gcc/cp/pt.cc > +++ b/gcc/cp/pt.cc > @@ -3232,14 +3232,6 @@ check_explicit_specialization (tree declarator, > tree tmpl_func = DECL_TEMPLATE_RESULT (gen_tmpl); > gcc_assert (TREE_CODE (tmpl_func) == FUNCTION_DECL); > > - /* A concept cannot be specialized. */ > - if (DECL_DECLARED_CONCEPT_P (tmpl_func)) > - { > - error ("explicit specialization of function concept %qD", > - gen_tmpl); > - return error_mark_node; > - } > - > /* This specialization has the same linkage and visibility as > the function template it specializes. */ > TREE_PUBLIC (decl) = TREE_PUBLIC (tmpl_func); > @@ -5150,13 +5142,6 @@ process_partial_specialization (tree decl) > > gcc_assert (current_template_parms); > > - /* A concept cannot be specialized. */ > - if (flag_concepts && variable_concept_p (maintmpl)) > - { > - error ("specialization of variable concept %q#D", maintmpl); > - return error_mark_node; > - } > - > inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms); > ntparms = TREE_VEC_LENGTH (inner_parms); > > @@ -10532,9 +10517,6 @@ lookup_template_class (tree d1, tree arglist, tree > in_decl, tree context, > tree > lookup_template_variable (tree templ, tree arglist, tsubst_flags_t complain) > { > - if (flag_concepts && variable_concept_p (templ)) > - return build_concept_check (templ, arglist, tf_none); > - > tree gen_templ = most_general_template (templ); > tree parms = DECL_INNERMOST_TEMPLATE_PARMS (gen_templ); > arglist = add_outermost_template_args (templ, arglist); > @@ -20119,14 +20101,6 @@ tsubst_expr (tree t, tree args, tsubst_flags_t > complain, tree in_decl) > tree check = build_concept_check (templ, targs, complain); > if (check == error_mark_node) > RETURN (error_mark_node); > - > - tree id = unpack_concept_check (check); > - > - /* If we built a function concept check, return the underlying > - template-id. So we can evaluate it as a function call. */ > - if (function_concept_p (TREE_OPERAND (id, 0))) > - RETURN (id); > - > RETURN (check); > } > > @@ -21096,19 +21070,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t > complain, tree in_decl) > ret = build_offset_ref_call_from_tree (function, &call_args, > complain); > else if (concept_check_p (function)) > - { > - /* FUNCTION is a template-id referring to a concept definition. */ > - tree id = unpack_concept_check (function); > - tree tmpl = TREE_OPERAND (id, 0); > - tree args = TREE_OPERAND (id, 1); > - > - /* Calls to standard and variable concepts should have been > - previously diagnosed. */ > - gcc_assert (function_concept_p (tmpl)); > - > - /* Ensure the result is wrapped as a call expression. */ > - ret = build_concept_check (tmpl, args, tf_warning_or_error); > - } > + /* Calls to concepts should have been previously diagnosed. */ > + gcc_assert (false); > else > ret = finish_call_expr (function, &call_args, > /*disallow_virtual=*/qualified_p, > @@ -26414,14 +26377,6 @@ do_decl_instantiation (tree decl, tree storage) > error ("explicit instantiation of non-template %q#D", decl); > return; > } > - else if (DECL_DECLARED_CONCEPT_P (decl)) > - { > - if (VAR_P (decl)) > - error ("explicit instantiation of variable concept %q#D", decl); > - else > - error ("explicit instantiation of function concept %q#D", decl); > - return; > - } > > bool var_templ = (DECL_TEMPLATE_INFO (decl) > && variable_template_p (DECL_TI_TEMPLATE (decl))); > @@ -27211,9 +27166,6 @@ instantiate_decl (tree d, bool defer_ok, bool > expl_inst_class_mem_p) > functions and static member variables. */ > gcc_assert (VAR_OR_FUNCTION_DECL_P (d)); > > - /* A concept is never instantiated. */ > - gcc_assert (!DECL_DECLARED_CONCEPT_P (d)); > - > gcc_checking_assert (!DECL_FUNCTION_SCOPE_P (d)); > > if (modules_p ()) > @@ -29492,8 +29444,8 @@ make_constrained_decltype_auto (tree con, tree args) > static bool > placeholder_type_constraint_dependent_p (tree t) > { > - tree id = unpack_concept_check (t); > - tree args = TREE_OPERAND (id, 1); > + gcc_assert (concept_check_p (t)); > + tree args = TREE_OPERAND (t, 1); > tree first = TREE_VEC_ELT (args, 0); > if (ARGUMENT_PACK_P (first)) > { > @@ -31452,8 +31404,8 @@ convert_generic_types_to_packs (tree parm, int > start_idx, int end_idx) > requirements. */ > if (tree constr = TEMPLATE_PARM_CONSTRAINTS (node)) > { > - tree id = unpack_concept_check (constr); > - TREE_VEC_ELT (TREE_OPERAND (id, 1), 0) = t; > + gcc_assert (concept_check_p (constr)); > + TREE_VEC_ELT (TREE_OPERAND (constr, 1), 0) = t; > /* Use UNKNOWN_LOCATION so write_template_args can tell the > difference between this and a fold the user wrote. */ > location_t loc = UNKNOWN_LOCATION; > diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc > index 669da4ad969..e58612660c9 100644 > --- a/gcc/cp/semantics.cc > +++ b/gcc/cp/semantics.cc > @@ -3067,20 +3067,9 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, > bool disallow_virtual, > } > else if (concept_check_p (fn)) > { > - /* FN is actually a template-id referring to a concept definition. */ > - tree id = unpack_concept_check (fn); > - tree tmpl = TREE_OPERAND (id, 0); > - tree args = TREE_OPERAND (id, 1); > - > - if (!function_concept_p (tmpl)) > - { > - error_at (EXPR_LOC_OR_LOC (fn, input_location), > - "cannot call a concept as a function"); > - return error_mark_node; > - } > - > - /* Ensure the result is wrapped as a call expression. */ > - result = build_concept_check (tmpl, args, tf_warning_or_error); > + error_at (EXPR_LOC_OR_LOC (fn, input_location), > + "cannot call a concept as a function"); > + return error_mark_node; > } > else if (is_overloaded_fn (fn)) > { > diff --git a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C > b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C > index 0d10ce1ea9f..2bf1cd5ab17 100644 > --- a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C > +++ b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C > @@ -7,8 +7,8 @@ typedef concept int CINT; // { dg-error "'concept' cannot > appear in a typedef de > void f(concept int); // { dg-error "a parameter cannot be declared > 'concept'" } > > template<typename T> > -concept int f2() { return 0; } // { dg-error "return type" } > -concept bool f3(); // { dg-error "14:concept .f3. has no definition" } > +concept int f2() { return 0; } // { dg-error "function concepts are no > longer supported" } > +concept bool f3(); // { dg-error "14:function concepts are no longer > supported" } > // { dg-error "keyword is not allowed" "" { target *-*-* } > .-1 } > > struct X > @@ -26,11 +26,11 @@ struct X > concept X(); // { dg-error "a constructor cannot be 'concept'" } > }; > > -concept bool X2; // { dg-error "non-template variable" } > +concept bool X2; // { dg-error "variable" } > // { dg-error "keyword is not allowed" "" { target *-*-* } .-1 > } > > template<typename T> > - concept bool X3; // { dg-error "has no initializer" } > + concept bool X3; // { dg-error "variable concepts" } > // { dg-error "keyword is not allowed" "" { target *-*-* } > .-1 } > > struct S { > diff --git a/gcc/testsuite/g++.dg/concepts/fn-concept2.C > b/gcc/testsuite/g++.dg/concepts/fn-concept2.C > index 799e85de955..52ca8245c76 100644 > --- a/gcc/testsuite/g++.dg/concepts/fn-concept2.C > +++ b/gcc/testsuite/g++.dg/concepts/fn-concept2.C > @@ -3,7 +3,7 @@ > // { dg-prune-output "concept definition syntax is" } > > template<typename T> > - concept auto C1() { return 0; } // { dg-error "16:concept .concept auto > C1\\(\\). declared with a deduced return type" } > + concept auto C1() { return 0; } // { dg-error "16:function concepts are no > longer supported" } > > template<typename T> > - concept int C2() { return 0; } // { dg-error "15:concept .concept int > C2\\(\\). with non-.bool. return type .int." } > + concept int C2() { return 0; } // { dg-error "15:function concepts are no > longer supported" } > diff --git a/gcc/testsuite/g++.dg/concepts/pr71128.C > b/gcc/testsuite/g++.dg/concepts/pr71128.C > index 63b3d1dff78..a3d5357d432 100644 > --- a/gcc/testsuite/g++.dg/concepts/pr71128.C > +++ b/gcc/testsuite/g++.dg/concepts/pr71128.C > @@ -2,9 +2,9 @@ > // { dg-options "-fconcepts" } > > template<typename T> > -concept bool C() { return true; } // { dg-error "the .bool. keyword" } > -template bool C<int>(); // { dg-error "explicit instantiation of function > concept" } > +concept bool C() { return true; } // { dg-error "the .bool. keyword|function > concepts" } > +template bool C<int>(); // { dg-error "template function|not a function > template|expected" } > > template<typename T> > -concept bool D = true; // { dg-error "the .bool. keyword" } > -template bool D<int>; // { dg-error "explicit instantiation of variable > concept" } > +concept bool D = true; // { dg-error "the .bool. keyword|variable > concepts are no longer supported" } > +template bool D<int>; // { dg-error "not a template function|expected" } > diff --git a/gcc/testsuite/g++.dg/concepts/var-concept6.C > b/gcc/testsuite/g++.dg/concepts/var-concept6.C > index 04298f47a92..062007a1291 100644 > --- a/gcc/testsuite/g++.dg/concepts/var-concept6.C > +++ b/gcc/testsuite/g++.dg/concepts/var-concept6.C > @@ -2,4 +2,4 @@ > // { dg-options "-fconcepts" } > > template <class T> > -concept int C = true; // { dg-error "concept definition > syntax" } > +concept int C = true; // { dg-error "concept definition > syntax|variable concepts are no longer supported" } > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts.C > b/gcc/testsuite/g++.dg/cpp2a/concepts.C > index ebeeebf60bb..1b7a708659b 100644 > --- a/gcc/testsuite/g++.dg/cpp2a/concepts.C > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts.C > @@ -18,9 +18,9 @@ void f3(T) > { } > > template<typename T> > -concept bool C1 = true; // { dg-error "bool" } > +concept bool C1 = true; // { dg-error "bool|variable concepts" } > template<typename T> > -bool concept C2 = true; // { dg-error "concept definition syntax" } > +bool concept C2 = true; // { dg-error "concept definition syntax|variable > concepts" } > > template<typename T> > concept C3 = true; // OK > > base-commit: a10436a8404ad2f0cc5aa4d6a0cc850abe5ef49e > -- > 2.45.2 > >