aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2024-08-01 15:39:10 -0400
committerMarek Polacek <polacek@redhat.com>2024-08-05 20:56:31 -0400
commit935e82248873c3798d4ede742a75ad10e99257ad (patch)
tree848f80a1101c6e281669ac4cc2e59d8144914a6f
parent8ac4db24e43b09726f87f04213f782dce1b3ae47 (diff)
downloadgcc-935e82248873c3798d4ede742a75ad10e99257ad.zip
gcc-935e82248873c3798d4ede742a75ad10e99257ad.tar.gz
gcc-935e82248873c3798d4ede742a75ad10e99257ad.tar.bz2
c++: remove function/var concepts code
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. Simplify. * 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.
-rw-r--r--gcc/cp/constexpr.cc14
-rw-r--r--gcc/cp/constraint.cc346
-rw-r--r--gcc/cp/cp-tree.h71
-rw-r--r--gcc/cp/decl.cc120
-rw-r--r--gcc/cp/decl2.cc4
-rw-r--r--gcc/cp/error.cc11
-rw-r--r--gcc/cp/mangle.cc4
-rw-r--r--gcc/cp/parser.cc16
-rw-r--r--gcc/cp/pt.cc60
-rw-r--r--gcc/cp/semantics.cc17
-rw-r--r--gcc/testsuite/g++.dg/concepts/decl-diagnose.C8
-rw-r--r--gcc/testsuite/g++.dg/concepts/fn-concept2.C4
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr71128.C8
-rw-r--r--gcc/testsuite/g++.dg/concepts/var-concept6.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts.C4
15 files changed, 64 insertions, 625 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index 8277b3b..8d994f0 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -8508,19 +8508,7 @@ 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);
- 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;
- }
+ gcc_assert (concept_check_p (t));
if (!value_dependent_expression_p (t)
&& !uid_sensitive_constexpr_evaluation_p ())
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 853ea8c..f79407f 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 an atomic 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 911d1d7..b81bc91 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) \
@@ -8583,7 +8577,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);
@@ -8606,7 +8599,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);
@@ -8868,69 +8860,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. */
@@ -8946,8 +8881,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 641d44b..86d2bfa 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))
@@ -11399,7 +11307,7 @@ grokvardecl (tree type,
// Handle explicit specializations and instantiations of variable templates.
if (orig_declarator)
decl = check_explicit_specialization (orig_declarator, decl,
- template_count, conceptp * 8);
+ template_count, 0);
return decl != error_mark_node ? decl : NULL_TREE;
}
@@ -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 6d67468..695d5f8 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 d80bac8..da853e2 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,10 +3950,7 @@ 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);
- if (OVL_P (tmpl))
- tmpl = OVL_FIRST (tmpl);
+ tree tmpl = TREE_OPERAND (expr, 0);
print_location (context, DECL_SOURCE_LOCATION (tmpl));
diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
index e739122..46dc692 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 eb102de..f625b0a 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 77fa590..35a9c56 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 669da4a..e586126 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 0d10ce1..2bf1cd5 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 799e85d..52ca824 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 63b3d1d..a3d5357 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 04298f4..062007a 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 ebeeebf..1b7a708 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