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>.

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

Reply via email to