@@ -1099,12 +1099,7 @@ c_cpp_builtins (cpp_reader *pfile)
cpp_define (pfile, "__cpp_variadic_friend=202403L");
}
if (flag_concepts)
- {
- if (cxx_dialect >= cxx20 || !flag_concepts_ts)
- cpp_define (pfile, "__cpp_concepts=202002L");
- else
- cpp_define (pfile, "__cpp_concepts=201507L");
- }
+ cpp_define (pfile, "__cpp_concepts=202002L");
if (flag_contracts)
{
cpp_define (pfile, "__cpp_contracts=201906L");
@@ -1148,18 +1148,11 @@ c_common_post_options (const char **pfilename)
if (warn_return_type == -1 && c_dialect_cxx ())
warn_return_type = 1;
- /* C++20 is the final version of concepts. We still use -fconcepts
- to know when concepts are enabled. Note that -fconcepts-ts can
- be used to include additional features, although modified to
- work with the standard. */
- if (cxx_dialect >= cxx20 || flag_concepts_ts)
+ /* C++20 is the final version of concepts. We still use -fconcepts
+ to know when concepts are enabled. */
+ if (cxx_dialect >= cxx20)
flag_concepts = 1;
- /* -fconcepts-ts will be removed in GCC 15. */
- if (flag_concepts_ts)
- inform (input_location, "%<-fconcepts-ts%> is deprecated and will be "
- "removed in GCC 15; please convert your code to C++20 concepts");
-
/* -fimmediate-escalation has no effect when immediate functions are not
supported. */
if (flag_immediate_escalation && cxx_dialect < cxx20)
@@ -1721,8 +1721,8 @@ C++ ObjC++ Var(flag_concepts)
Enable support for C++ concepts.
fconcepts-ts
-C++ ObjC++ Var(flag_concepts_ts) Init(0)
-Enable certain features present in the Concepts TS.
+C++ ObjC++ WarnRemoved
+Removed in GCC 15. This switch has no effect.
fconcepts-diagnostics-depth=
C++ ObjC++ Joined RejectNegative UInteger Var(concepts_diagnostics_max_depth) Init(1)
@@ -984,9 +984,6 @@ UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fchar8_005ft)
fconcepts
UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fconcepts)
-fconcepts-ts
-UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-fconcepts-ts)
-
fcond-mismatch
UrlSuffix(gcc/C-Dialect-Options.html#index-fcond-mismatch)
@@ -437,18 +437,6 @@ deduce_constrained_parameter (tree expr, tree& check, tree& proto)
return false;
}
-/* Given a call expression or template-id expression to a concept, EXPR,
- deduce the concept being checked and return the template arguments.
- Returns NULL_TREE if deduction fails. */
-static tree
-deduce_concept_introduction (tree check)
-{
- tree info = resolve_concept_check (check);
- if (info && info != error_mark_node)
- return TREE_PURPOSE (info);
- return NULL_TREE;
-}
-
/* Build a constrained placeholder type where SPEC is a type-constraint.
SPEC can be anything were concept_definition_p is true.
@@ -1578,18 +1566,6 @@ finish_shorthand_constraint (tree decl, tree constr)
tree con = CONSTRAINED_PARM_CONCEPT (constr);
tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
- /* The TS lets use shorthand to constrain a pack of arguments, but the
- standard does not.
-
- For the TS, consider:
-
- template<C... Ts> struct s;
-
- If C is variadic (and because Ts is a pack), we associate the
- constraint C<Ts...>. In all other cases, we associate
- the constraint (C<Ts> && ...).
-
- The standard behavior cannot be overridden by -fconcepts-ts. */
bool variadic_concept_p = template_parameter_pack_p (proto);
bool declared_pack_p = template_parameter_pack_p (decl);
bool apply_to_each_p = (cxx_dialect >= cxx20) ? true : !variadic_concept_p;
@@ -1635,264 +1611,6 @@ get_shorthand_constraints (tree parms)
return result;
}
-/* Get the deduced wildcard from a DEDUCED placeholder. If the deduced
- wildcard is a pack, return the first argument of that pack. */
-
-static tree
-get_deduced_wildcard (tree wildcard)
-{
- if (ARGUMENT_PACK_P (wildcard))
- wildcard = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (wildcard), 0);
- gcc_assert (TREE_CODE (wildcard) == WILDCARD_DECL);
- return wildcard;
-}
-
-/* Returns the prototype parameter for the nth deduced wildcard. */
-
-static tree
-get_introduction_prototype (tree wildcards, int index)
-{
- return TREE_TYPE (get_deduced_wildcard (TREE_VEC_ELT (wildcards, index)));
-}
-
-/* Introduce a type template parameter. */
-
-static tree
-introduce_type_template_parameter (tree wildcard, bool& non_type_p)
-{
- non_type_p = false;
- return finish_template_type_parm (class_type_node, DECL_NAME (wildcard));
-}
-
-/* Introduce a template template parameter. */
-
-static tree
-introduce_template_template_parameter (tree wildcard, bool& non_type_p)
-{
- non_type_p = false;
- begin_template_parm_list ();
- current_template_parms = DECL_TEMPLATE_PARMS (TREE_TYPE (wildcard));
- end_template_parm_list ();
- return finish_template_template_parm (class_type_node, DECL_NAME (wildcard));
-}
-
-/* Introduce a template non-type parameter. */
-
-static tree
-introduce_nontype_template_parameter (tree wildcard, bool& non_type_p)
-{
- non_type_p = true;
- tree parm = copy_decl (TREE_TYPE (wildcard));
- DECL_NAME (parm) = DECL_NAME (wildcard);
- return parm;
-}
-
-/* Introduce a single template parameter. */
-
-static tree
-build_introduced_template_parameter (tree wildcard, bool& non_type_p)
-{
- tree proto = TREE_TYPE (wildcard);
-
- tree parm;
- if (TREE_CODE (proto) == TYPE_DECL)
- parm = introduce_type_template_parameter (wildcard, non_type_p);
- else if (TREE_CODE (proto) == TEMPLATE_DECL)
- parm = introduce_template_template_parameter (wildcard, non_type_p);
- else
- parm = introduce_nontype_template_parameter (wildcard, non_type_p);
-
- /* Wrap in a TREE_LIST for process_template_parm. Note that introduced
- parameters do not retain the defaults from the source parameter. */
- return build_tree_list (NULL_TREE, parm);
-}
-
-/* Introduce a single template parameter. */
-
-static tree
-introduce_template_parameter (tree parms, tree wildcard)
-{
- gcc_assert (!ARGUMENT_PACK_P (wildcard));
- tree proto = TREE_TYPE (wildcard);
- location_t loc = DECL_SOURCE_LOCATION (wildcard);
-
- /* Diagnose the case where we have C{...Args}. */
- if (WILDCARD_PACK_P (wildcard))
- {
- tree id = DECL_NAME (wildcard);
- error_at (loc, "%qE cannot be introduced with an ellipsis %<...%>", id);
- inform (DECL_SOURCE_LOCATION (proto), "prototype declared here");
- }
-
- bool non_type_p;
- tree parm = build_introduced_template_parameter (wildcard, non_type_p);
- return process_template_parm (parms, loc, parm, non_type_p, false);
-}
-
-/* Introduce a template parameter pack. */
-
-static tree
-introduce_template_parameter_pack (tree parms, tree wildcard)
-{
- bool non_type_p;
- tree parm = build_introduced_template_parameter (wildcard, non_type_p);
- location_t loc = DECL_SOURCE_LOCATION (wildcard);
- return process_template_parm (parms, loc, parm, non_type_p, true);
-}
-
-/* Introduce the nth template parameter. */
-
-static tree
-introduce_template_parameter (tree parms, tree wildcards, int& index)
-{
- tree deduced = TREE_VEC_ELT (wildcards, index++);
- return introduce_template_parameter (parms, deduced);
-}
-
-/* Introduce either a template parameter pack or a list of template
- parameters. */
-
-static tree
-introduce_template_parameters (tree parms, tree wildcards, int& index)
-{
- /* If the prototype was a parameter, we better have deduced an
- argument pack, and that argument must be the last deduced value
- in the wildcard vector. */
- tree deduced = TREE_VEC_ELT (wildcards, index++);
- gcc_assert (ARGUMENT_PACK_P (deduced));
- gcc_assert (index == TREE_VEC_LENGTH (wildcards));
-
- /* Introduce each element in the pack. */
- tree args = ARGUMENT_PACK_ARGS (deduced);
- for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
- {
- tree arg = TREE_VEC_ELT (args, i);
- if (WILDCARD_PACK_P (arg))
- parms = introduce_template_parameter_pack (parms, arg);
- else
- parms = introduce_template_parameter (parms, arg);
- }
-
- return parms;
-}
-
-/* Builds the template parameter list PARMS by chaining introduced
- parameters from the WILDCARD vector. INDEX is the position of
- the current parameter. */
-
-static tree
-process_introduction_parms (tree parms, tree wildcards, int& index)
-{
- tree proto = get_introduction_prototype (wildcards, index);
- if (template_parameter_pack_p (proto))
- return introduce_template_parameters (parms, wildcards, index);
- else
- return introduce_template_parameter (parms, wildcards, index);
-}
-
-/* Ensure that all template parameters have been introduced for the concept
- named in CHECK. If not, emit a diagnostic.
-
- Note that implicitly introducing a parameter with a default argument
- creates a case where a parameter is declared, but unnamed, making
- it unusable in the definition. */
-
-static bool
-check_introduction_list (tree intros, tree check)
-{
- check = unpack_concept_check (check);
- tree tmpl = TREE_OPERAND (check, 0);
- if (OVL_P (tmpl))
- tmpl = OVL_FIRST (tmpl);
-
- tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
- if (TREE_VEC_LENGTH (intros) < TREE_VEC_LENGTH (parms))
- {
- error_at (input_location, "all template parameters of %qD must "
- "be introduced", tmpl);
- return false;
- }
-
- return true;
-}
-
-/* Associates a constraint check to the current template based on the
- introduction parameters. INTRO_LIST must be a TREE_VEC of WILDCARD_DECLs
- containing a chained PARM_DECL which contains the identifier as well as
- the source location. TMPL_DECL is the decl for the concept being used.
- If we take a concept, C, this will form a check in the form of
- C<INTRO_LIST> filling in any extra arguments needed by the defaults
- deduced.
-
- Returns NULL_TREE if no concept could be matched and error_mark_node if
- an error occurred when matching. */
-
-tree
-finish_template_introduction (tree tmpl_decl,
- tree intro_list,
- location_t intro_loc)
-{
- /* Build a concept check to deduce the actual parameters. */
- tree expr = build_concept_check (tmpl_decl, intro_list, tf_none);
- if (expr == error_mark_node)
- {
- error_at (intro_loc, "cannot deduce template parameters from "
- "introduction list");
- return error_mark_node;
- }
-
- if (!check_introduction_list (intro_list, expr))
- return error_mark_node;
-
- tree parms = deduce_concept_introduction (expr);
- if (!parms)
- return NULL_TREE;
-
- /* Build template parameter scope for introduction. */
- tree parm_list = NULL_TREE;
- begin_template_parm_list ();
- int nargs = MIN (TREE_VEC_LENGTH (parms), TREE_VEC_LENGTH (intro_list));
- for (int n = 0; n < nargs; )
- parm_list = process_introduction_parms (parm_list, parms, n);
- parm_list = end_template_parm_list (parm_list);
-
- /* Update the number of arguments to reflect the number of deduced
- template parameter introductions. */
- nargs = TREE_VEC_LENGTH (parm_list);
-
- /* Determine if any errors occurred during matching. */
- for (int i = 0; i < TREE_VEC_LENGTH (parm_list); ++i)
- if (TREE_VALUE (TREE_VEC_ELT (parm_list, i)) == error_mark_node)
- {
- end_template_decl ();
- return error_mark_node;
- }
-
- /* Build a concept check for our constraint. */
- tree check_args = make_tree_vec (nargs);
- int n = 0;
- for (; n < TREE_VEC_LENGTH (parm_list); ++n)
- {
- tree parm = TREE_VEC_ELT (parm_list, n);
- TREE_VEC_ELT (check_args, n) = template_parm_to_arg (parm);
- }
- SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (check_args, n);
-
- /* If the template expects more parameters we should be able
- to use the defaults from our deduced concept. */
- for (; n < TREE_VEC_LENGTH (parms); ++n)
- TREE_VEC_ELT (check_args, n) = TREE_VEC_ELT (parms, n);
-
- /* Associate the constraint. */
- tree check = build_concept_check (tmpl_decl,
- check_args,
- tf_warning_or_error);
- TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = check;
-
- return parm_list;
-}
-
-
/* Given the concept check T from a constrained-type-specifier, extract
its TMPL and ARGS. FIXME why do we need two different forms of
constrained-type-specifier? */
@@ -7482,7 +7482,6 @@ extern tree canonical_type_parameter (tree);
extern void push_access_scope (tree);
extern void pop_access_scope (tree);
extern bool check_template_shadow (tree);
-extern bool check_auto_in_tmpl_args (tree, tree);
extern tree get_innermost_template_args (tree, int);
extern void maybe_begin_member_template_processing (tree);
extern void maybe_end_member_template_processing (void);
@@ -8584,7 +8583,6 @@ extern hashval_t hash_placeholder_constraint (tree);
extern bool deduce_constrained_parameter (tree, tree&, tree&);
extern tree resolve_constraint_check (tree);
extern tree check_function_concept (tree);
-extern tree finish_template_introduction (tree, tree, location_t loc);
extern bool valid_requirements_p (tree);
extern tree finish_concept_name (tree);
extern tree finish_shorthand_constraint (tree, tree);
@@ -1004,16 +1004,6 @@ member_like_constrained_friend_p (tree decl)
static bool
function_requirements_equivalent_p (tree newfn, tree oldfn)
{
- /* In the concepts TS, the combined constraints are compared. */
- if (cxx_dialect < cxx20)
- {
- tree ci1 = get_constraints (oldfn);
- tree ci2 = get_constraints (newfn);
- tree req1 = ci1 ? CI_ASSOCIATED_CONSTRAINTS (ci1) : NULL_TREE;
- tree req2 = ci2 ? CI_ASSOCIATED_CONSTRAINTS (ci2) : NULL_TREE;
- return cp_tree_equal (req1, req2);
- }
-
/* [temp.friend]/9 "Such a constrained friend function does not declare the
same function as a declaration in any other scope." So no need to
actually compare the requirements. */
@@ -10619,9 +10609,8 @@ grokfndecl (tree ctype,
template shall be a definition. */
if (ci
&& (block_local
- || (!flag_concepts_ts
- && (!processing_template_decl
- || (friendp && !memtmpl && !funcdef_flag)))))
+ || !processing_template_decl
+ || (friendp && !memtmpl && !funcdef_flag)))
{
if (!friendp || !processing_template_decl)
error_at (location, "constraints on a non-templated function");
@@ -11324,9 +11313,6 @@ grokvardecl (tree type,
}
else
DECL_DECLARED_CONCEPT_P (decl) = true;
- if (!same_type_ignoring_top_level_qualifiers_p (type, boolean_type_node))
- error_at (declspecs->locations[ds_type_spec],
- "concept must have type %<bool%>");
if (TEMPLATE_PARMS_CONSTRAINTS (current_template_parms))
{
error_at (location, "a variable concept cannot be constrained");
@@ -16595,16 +16595,15 @@ cp_parser_decl_specifier_seq (cp_parser* parser,
/* Warn for concept as a decl-specifier. We'll rewrite these as
concept declarations later. */
- if (!flag_concepts_ts)
- {
- cp_token *next = cp_lexer_peek_token (parser->lexer);
- if (next->keyword == RID_BOOL)
- permerror (next->location, "the %<bool%> keyword is not "
- "allowed in a C++20 concept definition");
- else
- error_at (token->location, "C++20 concept definition syntax "
- "is %<concept <name> = <expr>%>");
- }
+ {
+ cp_token *next = cp_lexer_peek_token (parser->lexer);
+ if (next->keyword == RID_BOOL)
+ permerror (next->location, "the %<bool%> keyword is not "
+ "allowed in a C++20 concept definition");
+ else
+ error_at (token->location, "C++20 concept definition syntax "
+ "is %<concept <name> = <expr>%>");
+ }
/* In C++20 a concept definition is just 'concept name = expr;'
Support that syntax as a TS extension by pretending we've seen
@@ -18402,61 +18401,6 @@ cp_parser_template_parameter_list (cp_parser* parser)
return end_template_parm_list (parameter_list);
}
-/* Parse a introduction-list.
-
- introduction-list:
- introduced-parameter
- introduction-list , introduced-parameter
-
- introduced-parameter:
- ...[opt] identifier
-
- Returns a TREE_VEC of WILDCARD_DECLs. If the parameter is a pack
- then the introduced parm will have WILDCARD_PACK_P set. In addition, the
- WILDCARD_DECL will also have DECL_NAME set and token location in
- DECL_SOURCE_LOCATION. */
-
-static tree
-cp_parser_introduction_list (cp_parser *parser)
-{
- vec<tree, va_gc> *introduction_vec = make_tree_vector ();
-
- while (true)
- {
- bool is_pack = cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS);
- if (is_pack)
- cp_lexer_consume_token (parser->lexer);
-
- tree identifier = cp_parser_identifier (parser);
- if (identifier == error_mark_node)
- break;
-
- /* Build placeholder. */
- tree parm = build_nt (WILDCARD_DECL);
- DECL_SOURCE_LOCATION (parm)
- = cp_lexer_peek_token (parser->lexer)->location;
- DECL_NAME (parm) = identifier;
- WILDCARD_PACK_P (parm) = is_pack;
- vec_safe_push (introduction_vec, parm);
-
- /* If the next token is not a `,', we're done. */
- if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
- break;
- /* Otherwise, consume the `,' token. */
- cp_lexer_consume_token (parser->lexer);
- }
-
- /* Convert the vec into a TREE_VEC. */
- tree introduction_list = make_tree_vec (introduction_vec->length ());
- unsigned int n;
- tree parm;
- FOR_EACH_VEC_ELT (*introduction_vec, n, parm)
- TREE_VEC_ELT (introduction_list, n) = parm;
-
- release_tree_vector (introduction_vec);
- return introduction_list;
-}
-
/* Given a declarator, get the declarator-id part, or NULL_TREE if this
is an abstract declarator. */
@@ -19189,16 +19133,8 @@ cp_parser_template_id (cp_parser *parser,
location_t combined_loc
= make_location (token->location, token->location, parser->lexer);
- /* Check for concepts autos where they don't belong. We could
- identify types in some cases of identifier TEMPL, looking ahead
- for a CPP_SCOPE, but that would buy us nothing: we accept auto in
- types. We reject them in functions, but if what we have is an
- identifier, even with none_type we can't conclude it's NOT a
- type, we have to wait for template substitution. */
- if (flag_concepts && check_auto_in_tmpl_args (templ, arguments))
- template_id = error_mark_node;
/* Build a representation of the specialization. */
- else if (identifier_p (templ))
+ if (identifier_p (templ))
template_id = build_min_nt_loc (combined_loc,
TEMPLATE_ID_EXPR,
templ, arguments);
@@ -20520,10 +20456,9 @@ cp_parser_simple_type_specifier (cp_parser* parser,
"only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
}
- else if (!flag_concepts_ts && parser->in_template_argument_list_p)
- pedwarn (token->location, 0,
- "use of %<auto%> in template argument "
- "only available with %<-fconcepts-ts%>");
+ else if (parser->in_template_argument_list_p)
+ error_at (token->location,
+ "use of %<auto%> in template argument");
else if (!flag_concepts)
pedwarn (token->location, 0,
"use of %<auto%> in parameter declaration "
@@ -20866,10 +20801,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
TENTATIVE is true if the type-specifier parsing is tentative; in that case,
don't give an error if TMPL isn't a valid type-constraint, as the template-id
- might actually be a concept-check,
-
- Note that the Concepts TS allows the auto or decltype(auto) to be
- omitted in a constrained-type-specifier. */
+ might actually be a concept-check. */
static tree
cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
@@ -20900,38 +20832,29 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
if (con == error_mark_node)
return error_mark_node;
- /* As per the standard, require auto or decltype(auto), except in some
- cases (template parameter lists, -fconcepts-ts enabled). */
+ /* As per the standard, require auto or decltype(auto). */
cp_token *placeholder = NULL, *close_paren = NULL;
- if (cxx_dialect >= cxx20)
+ if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
+ placeholder = cp_lexer_consume_token (parser->lexer);
+ else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DECLTYPE))
{
- if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
- placeholder = cp_lexer_consume_token (parser->lexer);
- else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DECLTYPE))
- {
- placeholder = cp_lexer_consume_token (parser->lexer);
- matching_parens parens;
- parens.require_open (parser);
- cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
- close_paren = parens.require_close (parser);
- }
+ placeholder = cp_lexer_consume_token (parser->lexer);
+ matching_parens parens;
+ parens.require_open (parser);
+ cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
+ close_paren = parens.require_close (parser);
}
/* A type constraint constrains a contextually determined type or type
- parameter pack. However, the Concepts TS does allow concepts
- to introduce non-type and template template parameters. */
+ parameter pack. */
if (TREE_CODE (proto) != TYPE_DECL)
{
- if (!flag_concepts_ts
- || !processing_template_parmlist)
+ if (!tentative)
{
- if (!tentative)
- {
- error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
- inform (DECL_SOURCE_LOCATION (con), "concept defined here");
- }
- return error_mark_node;
+ error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
+ inform (DECL_SOURCE_LOCATION (con), "concept defined here");
}
+ return error_mark_node;
}
/* In a template parameter list, a type-parameter can be introduced
@@ -20949,9 +20872,7 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
}
/* Diagnose issues placeholder issues. */
- if (!flag_concepts_ts
- && !parser->in_result_type_constraint_p
- && !placeholder)
+ if (!parser->in_result_type_constraint_p && !placeholder)
{
if (tentative)
/* Perhaps it's a concept-check expression (c++/91073). */
@@ -25216,14 +25137,11 @@ cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
abstract_declarator = NULL;
bool auto_typeid_ok = false;
- /* The concepts TS allows 'auto' as a type-id. */
- if (flag_concepts_ts)
- auto_typeid_ok = !parser->in_type_id_in_expr_p;
/* DR 625 prohibits use of auto as a template-argument. We allow 'auto'
outside the template-argument-list context here only for the sake of
diagnostic: grokdeclarator then can emit a better error message for
e.g. using T = auto. */
- else if (flag_concepts)
+ if (flag_concepts)
auto_typeid_ok = (!parser->in_type_id_in_expr_p
&& !parser->in_template_argument_list_p);
@@ -25297,7 +25215,7 @@ cp_parser_template_type_arg (cp_parser *parser)
parser->type_definition_forbidden_message = saved_message;
/* cp_parser_type_id_1 checks for auto, but only for
->auto_is_implicit_function_template_parm_p. */
- if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r))
+ if (cxx_dialect >= cxx14 && type_uses_auto (r))
{
error ("invalid use of %<auto%> in template argument");
r = error_mark_node;
@@ -31589,8 +31507,7 @@ cp_parser_constraint_logical_or_expression (cp_parser *parser, bool lambda_p)
return lhs;
}
-/* Parse the expression after a requires-clause. This has a different grammar
- than that in the concepts TS. */
+/* Parse the expression after a requires-clause. */
static tree
cp_parser_requires_clause_expression (cp_parser *parser, bool lambda_p)
@@ -31675,10 +31592,7 @@ cp_parser_requires_clause_opt (cp_parser *parser, bool lambda_p)
else
cp_lexer_consume_token (parser->lexer);
- if (!flag_concepts_ts)
- return cp_parser_requires_clause_expression (parser, lambda_p);
- else
- return cp_parser_constraint_expression (parser);
+ return cp_parser_requires_clause_expression (parser, lambda_p);
}
/*---------------------------------------------------------------------------
@@ -32053,7 +31967,7 @@ cp_parser_compound_requirement (cp_parser *parser)
return error_mark_node;
}
}
- else if (!flag_concepts_ts)
+ else
/* P1452R2 removed the trailing-return-type option. */
error_at (type_loc,
"return-type-requirement is not a type-constraint");
@@ -33199,110 +33113,6 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
vec_safe_push (unparsed_funs_with_definitions, decl);
}
-/* Parse a template introduction header for a template-declaration. Returns
- false if tentative parse fails. */
-
-static bool
-cp_parser_template_introduction (cp_parser* parser, bool member_p)
-{
- cp_parser_parse_tentatively (parser);
-
- tree saved_scope = parser->scope;
- tree saved_object_scope = parser->object_scope;
- tree saved_qualifying_scope = parser->qualifying_scope;
- bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
-
- cp_token *start_token = cp_lexer_peek_token (parser->lexer);
-
- /* In classes don't parse valid unnamed bitfields as invalid
- template introductions. */
- if (member_p)
- parser->colon_corrects_to_scope_p = false;
-
- /* Look for the optional `::' operator. */
- cp_parser_global_scope_opt (parser,
- /*current_scope_valid_p=*/false);
- /* Look for the nested-name-specifier. */
- cp_parser_nested_name_specifier_opt (parser,
- /*typename_keyword_p=*/false,
- /*check_dependency_p=*/true,
- /*type_p=*/false,
- /*is_declaration=*/false);
-
- cp_token *token = cp_lexer_peek_token (parser->lexer);
- tree concept_name = cp_parser_identifier (parser);
-
- /* Look up the concept for which we will be matching
- template parameters. */
- tree tmpl_decl = cp_parser_lookup_name_simple (parser, concept_name,
- token->location);
- parser->scope = saved_scope;
- parser->object_scope = saved_object_scope;
- parser->qualifying_scope = saved_qualifying_scope;
- parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
-
- if (concept_name == error_mark_node
- || (seen_error () && !concept_definition_p (tmpl_decl)))
- cp_parser_simulate_error (parser);
-
- /* Look for opening brace for introduction. */
- matching_braces braces;
- braces.require_open (parser);
- location_t open_loc = input_location;
-
- if (!cp_parser_parse_definitely (parser))
- return false;
-
- push_deferring_access_checks (dk_deferred);
-
- /* Build vector of placeholder parameters and grab
- matching identifiers. */
- tree introduction_list = cp_parser_introduction_list (parser);
-
- /* Look for closing brace for introduction. */
- if (!braces.require_close (parser))
- return true;
-
- /* The introduction-list shall not be empty. */
- int nargs = TREE_VEC_LENGTH (introduction_list);
- if (nargs == 0)
- {
- /* In cp_parser_introduction_list we have already issued an error. */
- return true;
- }
-
- if (tmpl_decl == error_mark_node)
- {
- cp_parser_name_lookup_error (parser, concept_name, tmpl_decl, NLE_NULL,
- token->location);
- return true;
- }
-
- /* Build and associate the constraint. */
- location_t introduction_loc = make_location (open_loc,
- start_token->location,
- parser->lexer);
- tree parms = finish_template_introduction (tmpl_decl,
- introduction_list,
- introduction_loc);
- if (parms && parms != error_mark_node)
- {
- if (!flag_concepts_ts)
- pedwarn (introduction_loc, 0, "template-introductions"
- " are not part of C++20 concepts; use %qs to enable",
- "-fconcepts-ts");
-
- cp_parser_template_declaration_after_parameters (parser, parms,
- member_p);
- return true;
- }
-
- if (parms == NULL_TREE)
- error_at (token->location, "no matching concept for template-introduction");
-
- return true;
-}
-
/* Parse a normal template-declaration following the template keyword. */
static void
@@ -33394,8 +33204,6 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
cp_parser_explicit_template_declaration (parser, member_p);
return true;
}
- else if (flag_concepts)
- return cp_parser_template_introduction (parser, member_p);
return false;
}
@@ -3476,10 +3476,6 @@ template_heads_equivalent_p (const_tree tmpl1, const_tree tmpl2)
tree parms1 = DECL_TEMPLATE_PARMS (tmpl1);
tree parms2 = DECL_TEMPLATE_PARMS (tmpl2);
- /* Don't change the matching rules for pre-C++20. */
- if (cxx_dialect < cxx20)
- return comp_template_parms (parms1, parms2);
-
/* ... have the same number of template parameters, and their
corresponding parameters are equivalent. */
if (!template_parameter_lists_equivalent_p (parms1, parms2))
@@ -3887,9 +3883,6 @@ struct find_parameter_pack_data
/* Set of AST nodes that have been visited by the traversal. */
hash_set<tree> *visited;
- /* True iff we're making a type pack expansion. */
- bool type_pack_expansion_p;
-
/* True iff we found a subtree that has the extra args mechanism. */
bool found_extra_args_tree_p = false;
};
@@ -3936,13 +3929,6 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
t = TYPE_MAIN_VARIANT (t);
/* FALLTHRU */
case TEMPLATE_TEMPLATE_PARM:
- /* If the placeholder appears in the decl-specifier-seq of a function
- parameter pack (14.6.3), or the type-specifier-seq of a type-id that
- is a pack expansion, the invented template parameter is a template
- parameter pack. */
- if (flag_concepts_ts && ppd->type_pack_expansion_p && is_auto (t)
- && TEMPLATE_TYPE_LEVEL (t) != 0)
- TEMPLATE_TYPE_PARAMETER_PACK (t) = true;
if (TEMPLATE_TYPE_PARAMETER_PACK (t))
parameter_pack_p = true;
break;
@@ -4061,18 +4047,10 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
}
case DECLTYPE_TYPE:
- {
- /* When traversing a DECLTYPE_TYPE_EXPR, we need to set
- type_pack_expansion_p to false so that any placeholders
- within the expression don't get marked as parameter packs. */
- bool type_pack_expansion_p = ppd->type_pack_expansion_p;
- ppd->type_pack_expansion_p = false;
- cp_walk_tree (&DECLTYPE_TYPE_EXPR (t), &find_parameter_packs_r,
- ppd, ppd->visited);
- ppd->type_pack_expansion_p = type_pack_expansion_p;
- *walk_subtrees = 0;
- return NULL_TREE;
- }
+ cp_walk_tree (&DECLTYPE_TYPE_EXPR (t), &find_parameter_packs_r,
+ ppd, ppd->visited);
+ *walk_subtrees = 0;
+ return NULL_TREE;
case IF_STMT:
cp_walk_tree (&IF_COND (t), &find_parameter_packs_r,
@@ -4126,7 +4104,6 @@ uses_parameter_packs (tree t)
struct find_parameter_pack_data ppd;
ppd.parameter_packs = ¶meter_packs;
ppd.visited = new hash_set<tree>;
- ppd.type_pack_expansion_p = false;
cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
delete ppd.visited;
return parameter_packs;
@@ -4177,7 +4154,6 @@ make_pack_expansion (tree arg, tsubst_flags_t complain)
class expansion. */
ppd.visited = new hash_set<tree>;
ppd.parameter_packs = ¶meter_packs;
- ppd.type_pack_expansion_p = false;
gcc_assert (TYPE_P (TREE_PURPOSE (arg)));
cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r,
&ppd, ppd.visited);
@@ -4243,7 +4219,6 @@ make_pack_expansion (tree arg, tsubst_flags_t complain)
/* Determine which parameter packs will be expanded. */
ppd.parameter_packs = ¶meter_packs;
ppd.visited = new hash_set<tree>;
- ppd.type_pack_expansion_p = TYPE_P (arg);
cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
delete ppd.visited;
@@ -4302,7 +4277,6 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */)
ppd.parameter_packs = ¶meter_packs;
ppd.visited = new hash_set<tree>;
- ppd.type_pack_expansion_p = false;
cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
delete ppd.visited;
@@ -5558,7 +5532,6 @@ fixed_parameter_pack_p (tree parm)
struct find_parameter_pack_data ppd;
ppd.parameter_packs = ¶meter_packs;
ppd.visited = new hash_set<tree>;
- ppd.type_pack_expansion_p = false;
fixed_parameter_pack_p_1 (parm, &ppd);
@@ -17353,15 +17326,6 @@ tsubst_qualified_id (tree qualified_id, tree args,
if (is_template)
{
- /* We may be repeating a check already done during parsing, but
- if it was well-formed and passed then, it will pass again
- now, and if it didn't, we wouldn't have got here. The case
- we want to catch is when we couldn't tell then, and can now,
- namely when templ prior to substitution was an
- identifier. */
- if (flag_concepts && check_auto_in_tmpl_args (expr, template_args))
- return error_mark_node;
-
if (variable_template_p (expr))
expr = lookup_and_finish_template_variable (expr, template_args,
complain);
@@ -29627,63 +29591,6 @@ auto_hash::equal (tree t1, tree t2)
return equivalent_placeholder_constraints (c1, c2);
}
-/* for_each_template_parm callback for extract_autos: if t is a (possibly
- constrained) auto, add it to the vector. */
-
-static int
-extract_autos_r (tree t, void *data)
-{
- hash_table<auto_hash> &hash = *(hash_table<auto_hash>*)data;
- if (is_auto (t) && !template_placeholder_p (t))
- {
- /* All the autos were built with index 0; fix that up now. */
- tree *p = hash.find_slot (t, INSERT);
- int idx;
- if (*p)
- /* If this is a repeated constrained-type-specifier, use the index we
- chose before. */
- idx = TEMPLATE_TYPE_IDX (*p);
- else
- {
- /* Otherwise this is new, so use the current count. */
- *p = t;
- idx = hash.elements () - 1;
- }
- if (idx != TEMPLATE_TYPE_IDX (t))
- {
- gcc_checking_assert (TEMPLATE_TYPE_IDX (t) == 0);
- gcc_checking_assert (TYPE_CANONICAL (t) != t);
- TEMPLATE_TYPE_IDX (t) = idx;
- TYPE_CANONICAL (t) = canonical_type_parameter (t);
- }
- }
-
- /* Always keep walking. */
- return 0;
-}
-
-/* Return a TREE_VEC of the 'auto's used in type under the Concepts TS, which
- says they can appear anywhere in the type. */
-
-static tree
-extract_autos (tree type)
-{
- hash_set<tree> visited;
- hash_table<auto_hash> hash (2);
-
- for_each_template_parm (type, extract_autos_r, &hash, &visited, true);
-
- tree tree_vec = make_tree_vec (hash.elements());
- for (tree elt : hash)
- {
- unsigned i = TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (elt));
- TREE_VEC_ELT (tree_vec, i)
- = build_tree_list (NULL_TREE, TYPE_NAME (elt));
- }
-
- return tree_vec;
-}
-
/* The stem for deduction guide names. */
const char *const dguide_base = "__dguide_";
@@ -31216,16 +31123,9 @@ do_auto_deduction (tree type, tree init, tree auto_node,
return error_mark_node;
tree parms = build_tree_list (NULL_TREE, type);
- tree tparms;
-
- if (flag_concepts_ts)
- tparms = extract_autos (type);
- else
- {
- tparms = make_tree_vec (1);
- TREE_VEC_ELT (tparms, 0)
- = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
- }
+ tree tparms = make_tree_vec (1);
+ TREE_VEC_ELT (tparms, 0)
+ = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
int val = type_unification_real (tparms, targs, parms, &init, 1, 0,
@@ -31437,66 +31337,7 @@ type_uses_auto (tree type)
if (PACK_EXPANSION_P (type))
type = PACK_EXPANSION_PATTERN (type);
- if (flag_concepts_ts)
- {
- /* The Concepts TS allows multiple autos in one type-specifier; just
- return the first one we find, do_auto_deduction will collect all of
- them. */
- if (uses_template_parms (type))
- return for_each_template_parm (type, is_auto_r, /*data*/NULL,
- /*visited*/NULL, /*nondeduced*/false);
- else
- return NULL_TREE;
- }
- else
- return find_type_usage (type, is_auto);
-}
-
-/* Report ill-formed occurrences of auto types in ARGUMENTS. If
- concepts are enabled, auto is acceptable in template arguments, but
- only when TEMPL identifies a template class. Return TRUE if any
- such errors were reported. */
-
-bool
-check_auto_in_tmpl_args (tree tmpl, tree args)
-{
- if (!flag_concepts_ts)
- /* Only the concepts TS allows 'auto' as a type-id; it'd otherwise
- have already been rejected by the parser more generally. */
- return false;
-
- /* If there were previous errors, nevermind. */
- if (!args || TREE_CODE (args) != TREE_VEC)
- return false;
-
- /* If TMPL is an identifier, we're parsing and we can't tell yet
- whether TMPL is supposed to be a type, a function or a variable.
- We'll only be able to tell during template substitution, so we
- expect to be called again then. If concepts are enabled and we
- know we have a type, we're ok. */
- if (identifier_p (tmpl)
- || (DECL_P (tmpl)
- && (DECL_TYPE_TEMPLATE_P (tmpl)
- || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))))
- return false;
-
- /* Quickly search for any occurrences of auto; usually there won't
- be any, and then we'll avoid allocating the vector. */
- if (!type_uses_auto (args))
- return false;
-
- bool errors = false;
-
- tree vec = extract_autos (args);
- for (int i = 0; i < TREE_VEC_LENGTH (vec); i++)
- {
- tree xauto = TREE_VALUE (TREE_VEC_ELT (vec, i));
- error_at (DECL_SOURCE_LOCATION (xauto),
- "invalid use of %qT in template argument", xauto);
- errors = true;
- }
-
- return errors;
+ return find_type_usage (type, is_auto);
}
/* Recursively walk over && expressions searching for EXPR. Return a reference
@@ -3216,20 +3216,11 @@ exhaustion is signalled by throwing @code{std::bad_alloc}. See also
@samp{new (nothrow)}.
@opindex fconcepts
-@opindex fconcepts-ts
@item -fconcepts
-@itemx -fconcepts-ts
Enable support for the C++ Concepts feature for constraining template
arguments. With @option{-std=c++20} and above, Concepts are part of
the language standard, so @option{-fconcepts} defaults to on.
-Some constructs that were allowed by the earlier C++ Extensions for
-Concepts Technical Specification, ISO 19217 (2015), but didn't make it
-into the standard, can additionally be enabled by
-@option{-fconcepts-ts}. The option @option{-fconcepts-ts} was deprecated
-in GCC 14 and may be removed in GCC 15; users are expected to convert
-their code to C++20 concepts.
-
@opindex fconstexpr-depth
@item -fconstexpr-depth=@var{n}
Set the maximum nested evaluation depth for C++11 constexpr functions
deleted file mode 100644
@@ -1,28 +0,0 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template <class T1, class T2> class A { };
-
-A<int, int> a;
-A<double, float> a2;
-A<double, double> a22;
-
-A<auto, auto> b = a;
-A<auto, auto> b1 = a2;
-
-template <class T> concept bool C = __is_same_as (T, int);
-
-A<C,C> b2 = a;
-A<C,C> b3 = a2; // { dg-error "" }
-A<C,C> b32 = a22; // { dg-error "" }
-
-template <class T> concept bool C2() { return __is_enum (T); }
-
-enum E1 { };
-enum E2 { };
-
-A<E1,E1> a3;
-A<C2,C2> b4 = a3;
-
-A<E1,E2> a4;
-A<C2,C2> b5 = a4; // { dg-error "" }
@@ -1,13 +1,13 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class...> class tuple {};
tuple<int> t;
-tuple<auto> y = t;
+tuple<auto> y = t; // { dg-error "invalid|cannot convert" }
tuple<int,double> t2;
-tuple<auto...> x = t2;
-tuple<auto...> x2 = t;
+tuple<auto...> x = t2; // { dg-error "invalid|cannot convert" }
+tuple<auto...> x2 = t; // { dg-error "invalid|cannot convert" }
-tuple<auto> y2 = t2; // { dg-error "" }
+tuple<auto> y2 = t2; // { dg-error "invalid|cannot convert" }
deleted file mode 100644
@@ -1,12 +0,0 @@
-// PR c++/85006
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template<typename... Ts> struct A {};
-
-template<typename... Us> A<auto...> foo() { return A{}; }
-
-void bar()
-{
- foo();
-}
@@ -1,9 +1,9 @@
// PR c++/101886
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename...> struct A { };
A<int, int> a;
-A<auto, auto> b1 = a;
-A<auto, auto> b2 = a;
+A<auto, auto> b1 = a; // { dg-error "invalid|cannot convert" }
+A<auto, auto> b2 = a; // { dg-error "invalid|cannot convert" }
deleted file mode 100644
@@ -1,14 +0,0 @@
-// PR c++/101886
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template<typename, typename> struct A { };
-
-template<class T>
-void f() {
- A<int, int> a;
- A<auto, auto> b1 = a;
- A<auto, auto> b2 = a;
-}
-
-template void f<int>();
@@ -1,8 +1,8 @@
// { dg-do compile { target c++14 } }
-// { dg-additional-options -fconcepts-ts }
+// { dg-additional-options -fconcepts }
template <class T> struct A { };
-void f(A<auto> a) { }
+void f(A<auto> a) { } // { dg-error "use of .auto. in template argument" }
int main()
{
f(A<int>());
@@ -1,6 +1,6 @@
// PR c++/110065
// { dg-do compile { target c++17 } }
-// { dg-additional-options -fconcepts-ts }
+// { dg-additional-options -fconcepts }
template <typename>
inline constexpr bool t = false;
@@ -1,8 +1,8 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T>
-concept bool Isint = __is_same_as(T,int);
+concept Isint = __is_same_as(T,int);
template <class T>
struct A
@@ -1,11 +1,11 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool One() { return sizeof(T) >= 4; }
+ concept One = sizeof(T) >= 4;
template<typename T>
- concept bool Two() { return One<T>() && sizeof(T) >= 8; }
+ concept Two = One<T> && sizeof(T) >= 8;
// Check ordering of partial specializaitons
template<typename T>
@@ -1,11 +1,11 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool One() { return sizeof(T) >= 4; }
+ concept One = sizeof(T) >= 4;
template<typename T>
- concept bool Two() { return One<T>() && sizeof(T) >= 8; }
+ concept Two = One<T> && sizeof(T) >= 8;
// Check that there is no ecsacpe hatch
template<Two T> struct S4 { };
@@ -1,11 +1,11 @@
// PR c++/84551
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template<typename> concept bool C() { return true; }
+template<typename> concept C = true;
-template<template<typename T> requires C<T>() class TT> struct A {};
+template<template<typename T> requires C<T> class TT> struct A {};
-template<typename U> requires C<U>() struct B {};
+template<typename U> requires C<U> struct B {};
A<B> a;
@@ -1,5 +1,6 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
+// { dg-prune-output "concept definition syntax is" }
typedef concept int CINT; // { dg-error "'concept' cannot appear in a typedef declaration" }
@@ -8,6 +9,7 @@ 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" }
+ // { dg-error "keyword is not allowed" "" { target *-*-* } .-1 }
struct X
{
@@ -18,17 +20,21 @@ struct X
static concept f6 = true; // { dg-error "declared 'concept'" }
static concept bool x; // { dg-error "declared 'concept'" }
// { dg-error "uninitialized 'const" "" { target *-*-* } .-1 }
+ // { dg-error "keyword is not allowed" "" { target *-*-* } .-2 }
concept int x2; // { dg-error "declared 'concept'" }
concept ~X(); // { dg-error "a destructor cannot be 'concept'" }
concept X(); // { dg-error "a constructor cannot be 'concept'" }
};
concept bool X2; // { dg-error "non-template variable" }
+ // { dg-error "keyword is not allowed" "" { target *-*-* } .-1 }
template<typename T>
concept bool X3; // { dg-error "has no initializer" }
+ // { dg-error "keyword is not allowed" "" { target *-*-* } .-1 }
struct S {
template<typename T>
static concept bool C1 = true; // { dg-error "static data member" }
+ // { dg-error "keyword is not allowed" "" { target *-*-* } .-1 }
};
@@ -1,13 +1,12 @@
// PR c++/67007
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++20 } }
template <class U>
-concept bool A =
+concept A =
requires (U u) { u; };
template <class T>
-concept bool B =
+concept B =
requires (T t) { { t } -> A; };
-void foo(B);
+void foo(B auto);
@@ -1,19 +1,19 @@
// PR c++/67159
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts -fconcepts-diagnostics-depth=2" }
template <class T, class U>
-concept bool SameAs = __is_same_as(T, U);
+concept SameAs = __is_same_as(T, U);
template <class T>
-concept bool R1 = requires (T& t) { // { dg-message "in requirements" }
- { t.begin() } -> T; // { dg-error "no match" }
- { t.end() } -> SameAs<T*>; // { dg-message "does not satisfy" }
+concept R1 = requires (T& t) {
+ { t.begin() } -> T; // { dg-error "no matching|return-type-requirement|too many" }
+ { t.end() } -> SameAs<T*>; // { dg-error "deduced expression type" }
};
template <class T>
-concept bool R2 = requires (T& t) { // { dg-message "in requirements" }
- { t.end() } -> SameAs<T*>; // { dg-message "does not satisfy" }
+concept R2 = requires (T& t) {
+ { t.end() } -> SameAs<T*>; // { dg-error "deduced expression type" }
};
struct foo {
@@ -21,10 +21,10 @@ struct foo {
int* end();
};
-R1{T}
+template<R1 T>
constexpr bool f() { return true; }
-R2{T}
+template<R2 T>
constexpr bool g() { return true; }
static_assert(f<foo>()); // { dg-error "" }
@@ -1,6 +1,6 @@
// PR c++/66092
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
#include <type_traits>
@@ -20,20 +20,15 @@ requires (sizeof...(Args) > 0)
}
template <typename T, typename U, typename... Args>
- concept bool Same()
- {
- return decltype(check<T, U, Args...>())::value;
- }
+ concept Same =
+ decltype(check<T, U, Args...>())::value;
template <typename T, typename U, typename... Args>
- concept bool Similar = true;
+ concept Similar = true;
template <typename... Args>
-requires Same<Args...>() // { dg-error "" "" { xfail *-*-* } }
+requires Same<Args...>() // { dg-error "" }
void foo( Args... args ) {}
-// FIXME: The new method of building concept checks is suppressing the
-// diagnostic for the invalid substitution. This produces an invalid
-// requires-clause, which still prevents the function from being resolved.
template <typename... Args>
requires Similar<Args...> // { dg-error "pack expansion" }
@@ -1,35 +1,35 @@
-// { dg-do link { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// Check equivalence of short- and longhand declarations.
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<typename T>
- concept bool D() { return __is_empty(T); }
+ concept D = __is_empty(T);
struct X { } x;
-void f1(C x);
+void f1(C auto x);
template<C T> void f2(T x);
-void f3(C x);
-template<C T> void f4(T x) requires D<T>();
-template<C T> void f5(T x) requires D<T>();
-template<C T> void f6(T x) requires D<T>();
+void f3(C auto x);
+template<C T> void f4(T x) requires D<T>;
+template<C T> void f5(T x) requires D<T>;
+template<C T> void f6(T x) requires D<T>;
+
+template<typename T> requires C<T> void f1(T x) { }
+template<typename T> requires C<T> void f2(T x) { }
+template<C T> void f3(T x) { }
+template<typename T> requires C<T> void f4(T x) requires D<T> { }
+template<typename T> requires C<T> and D<T> void f5(T x) { }
+template<typename T> void f6(T x) requires C<T> and D<T> { }
int main() {
- f1(x);
- f2(x);
- f3(x);
- f4(x);
- f5(x);
- f6(x);
+ f1(x); // { dg-error "ambiguous" }
+ f2(x); // { dg-error "ambiguous" }
+ f3(x); // { dg-error "ambiguous" }
+ f4(x); // { dg-error "ambiguous" }
+ f5(x); // { dg-error "ambiguous" }
+ f6(x); // { dg-error "ambiguous" }
}
-
-template<typename T> requires C<T>() void f1(T x) { }
-template<typename T> requires C<T>() void f2(T x) { }
-template<C T> void f3(T x) { }
-template<typename T> requires C<T>() void f4(T x) requires D<T>() { }
-template<typename T> requires C<T>() and D<T>() void f5(T x) { }
-template<typename T> void f6(T x) requires C<T>() and D<T>() { }
@@ -1,25 +1,18 @@
-// { dg-do link { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// template<typename T>
// concept bool C() { return true; }
template<typename T>
-concept bool C = true;
-
-void f1(C, C);
-void f2(C, C);
-void f3(C, C);
+concept C = true;
-int main() {
- f1(0, 0);
- f2(0, 0);
- f3(0, 0);
-}
+void f1(C auto, C auto);
+void f2(C auto, C auto);
+void f3(C auto, C auto);
-void f1(C, C) { }
+void f1(C auto, C auto) { }
template<C T1, C T2>
void f2(T1, T2) { }
@@ -27,3 +20,9 @@ void f2(T1, T2) { }
template<typename T, typename U>
requires C<T> && C<U>
void f3(T, U) { }
+
+int main() {
+ f1(0, 0);
+ f2(0, 0); // { dg-error "ambiguous" }
+ f3(0, 0); // { dg-error "ambiguous" }
+}
@@ -1,16 +1,14 @@
-// { dg-do run { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-// TODO: ICE on gimplify 16?
+// { dg-do run { target c++17 } }
+// { dg-options "-fconcepts" }
#include <cassert>
#include <iostream>
template<typename T>
- concept bool C1 = __is_class(T);
+ concept C1 = __is_class(T);
template<typename T>
- concept bool C3 = requires (T a) { ++a; };
+ concept C3 = requires (T a) { ++a; };
int main() {
if (C1<int>) assert(false);
@@ -1,24 +1,20 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool C1()
-{
- return requires (T t) { t.f(); }; // { dg-message "in requirements" }
-}
+concept C1 =
+ requires (T t) { t.f(); }; // { dg-message "in requirements" }
template<typename T>
-concept bool C2()
-{
- return requires { typename T::type; }; // { dg-message "in requirements" }
-}
+concept C2 =
+ requires { typename T::type; }; // { dg-message "in requirements" }
template<typename T>
- requires C1<T>()
+ requires C1<T>
void f1(T x) { }
template<typename T>
- requires C2<T>()
+ requires C2<T>
void f2(T x) { }
// Note that these declarations are private and therefore
@@ -38,6 +34,6 @@ int main()
// the constraint check before emitting the access check
// failures. The context is being presented consistently
// in both cases.
- static_assert(C1<S>(), ""); // { dg-error "failed" }
- static_assert(C2<S>(), ""); // { dg-error "" }
+ static_assert(C1<S>, ""); // { dg-error "failed" }
+ static_assert(C2<S>, ""); // { dg-error "" }
}
@@ -1,11 +1,9 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool C()
-{
- return requires (T& t) { t.~T(); };
-}
+concept C =
+ requires (T& t) { t.~T(); };
class S1
{
@@ -19,6 +17,6 @@ class S2
int main()
{
- static_assert(C<S1>(), ""); // { dg-error "failed" }
- static_assert(C<S2>(), ""); // { dg-error "failed" }
+ static_assert(C<S1>, ""); // { dg-error "failed" }
+ static_assert(C<S2>, ""); // { dg-error "failed" }
}
deleted file mode 100644
@@ -1,10 +0,0 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template<typename T>
- concept bool Tuple() { // { dg-error "multiple statements" }
- static_assert(T::value, "");
- return true;
- }
-
- void f(Tuple&);
@@ -1,11 +1,9 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
+// { 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" }
template<typename T>
concept int C2() { return 0; } // { dg-error "15:concept .concept int C2\\(\\). with non-.bool. return type .int." }
-
-template<typename T>
- concept bool C3(int) { return 0; } // { dg-error "16:concept .concept bool C3\\(int\\). declared with function parameters" }
@@ -1,6 +1,6 @@
// PR c++/92746
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template<typename T> concept bool C3() { return true; }
-static_assert(noexcept(C3<int>()), "function concept should be treated as if noexcept(true) specified");
+template<typename T> concept C3 = true;
+static_assert(noexcept(C3<int>), "function concept should be treated as if noexcept(true) specified");
@@ -1,13 +1,13 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
struct S { } s;
template<typename T>
- requires C<T>()
+ requires C<T>
void f(T x) { }
// Calls are valid when arguments are dependent,
@@ -1,5 +1,5 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// Test that constraint satisfaction checks work even when
// processing template declarations.
@@ -26,10 +26,7 @@ auto end(T const& t) -> decltype(t.end()) { return t.end(); }
template <typename T>
- concept bool Float()
- {
- return __is_same_as( T, float );
- }
+ concept Float = __is_same_as( T, float );
template <typename T>
constexpr decltype(auto) project( T t )
@@ -38,12 +35,9 @@ template <typename T>
}
template <typename T>
- concept bool Concept()
- {
- return requires( T t ) { // { dg-message "in requirements" }
- requires Float<decltype( project(t) )>();
+ concept Concept = requires( T t ) { // { dg-message "in requirements" }
+ requires Float<decltype( project(t) )>;
};
- }
template <Concept E, Concept F>
constexpr decltype(auto) operator<<( E&& e, F&& f ) {}
@@ -59,13 +53,11 @@ template <Concept T>
template <typename R>
-concept bool Range()
-{
- return requires( R r ) {
+concept Range =
+ requires( R r ) {
requires __is_same_as(
decltype(std::begin(r)), decltype(std::end(r)) );
};
-}
struct A
{
@@ -1,11 +1,11 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<typename T>
- requires C<T>()
+ requires C<T>
void f(T x) { }
// Non-dependent args are checked even in dependent scope.
@@ -1,15 +1,15 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
#include <cassert>
// Check partial ordering during overload resolution.
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<typename T>
- concept bool D() { return C<T>() and __is_empty(T); }
+ concept D = C<T> and __is_empty(T);
struct S1 { } s1;
struct S2 { int n; } s2;
@@ -1,11 +1,11 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<typename T>
- concept bool D() { return C<T>() and __is_empty(T); }
+ concept D = C<T> and __is_empty(T);
struct S1 { } s1;
struct S2 { int n; } s2;
@@ -1,19 +1,19 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// Check shorthand notation.
template<typename T>
- concept bool Type() { return true; }
+ concept Type = true;
template<typename T, typename U>
- concept bool Same() { return __is_same_as(T, U); }
+ concept Same = __is_same_as(T, U);
template<Same<int> T> struct S1 { };
template<typename T, Same<T> U> struct S2 { };
-void f(Same<int> q) { }
-void g(Type a, Same<decltype(a)> b) { }
+void f(Same<int> auto q) { }
+void g(Type auto a, Same<decltype(a)> auto b) { }
int main() {
S1<char> s1; // { dg-error "constraint|invalid" }
@@ -1,17 +1,17 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// Redefinition errors.
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<typename T>
- concept bool D() { return C<T>() and __is_empty(T); }
+ concept D = C<T> and __is_empty(T);
template<C T> void f(T x) { }
template<typename T>
- requires C<T>()
- void f(T x) { } // { dg-error "redefinition" }
+ requires C<T>
+ void f(T x) { }
int main() { }
@@ -1,6 +1,6 @@
// { dg-do link { target c++14 } }
-// { dg-options "-fconcepts-ts" }
+// { dg-options "-fconcepts" }
-void f() requires true { }
+void f() requires true { } // { dg-error "constraints on a non-templated function" }
int main() { }
@@ -1,8 +1,8 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool Class() { return __is_class(T); }
+ concept Class = __is_class(T);
template<Class T> void f(T) { }
@@ -1,13 +1,13 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
#include <cassert>
template<typename T>
- concept bool Class() { return __is_class(T); }
+ concept Class = __is_class(T);
template<typename T>
- concept bool Empty() { return Class<T>() and __is_empty(T); }
+ concept Empty = Class<T> and __is_empty(T);
template<Class T> int f(T) { return 1; }
template<Empty T> int f(T) { return 2; }
@@ -1,14 +1,14 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<int N>
- concept bool Int() { return true; }
+ concept Int = true;
template<template<typename> class X>
- concept bool Template() { return true; }
+ concept Template = true;
void f1(Int) { } // { dg-error "does not constrain a type" }
void f2(Template) { } // { dg-error "does not constrain a type" }
@@ -17,19 +17,19 @@ struct S { };
struct S1 {
void f1(auto x) { }
- void f2(C x) { }
+ void f2(C auto x) { }
void f3(auto x) { }
- void f3(C x) { }
+ void f3(C auto x) { }
};
template<C T>
struct S2 {
void f1(auto x) { }
- void f2(C x) { }
+ void f2(C auto x) { }
void h1(auto x);
- void h2(C x);
+ void h2(C auto x);
template<C U>
void g(T t, U u) { }
@@ -1,14 +1,14 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
#include <cassert>
#include <type_traits>
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<typename T>
- concept bool Type() { return true; }
+ concept Type = true;
struct S { };
@@ -16,36 +16,36 @@ int called;
// Basic terse notation
void f(auto x) { called = 1; }
-void g(C x) { called = 2; }
+void g(C auto x) { called = 2; }
// Overloading generic functions
void h(auto x) { called = 1; }
-void h(C x) { called = 2; }
+void h(C auto x) { called = 2; }
void p(auto x);
-void p(C x);
+void p(C auto x);
struct S1 {
void f1(auto x) { called = 1; }
- void f2(C x) { called = 2; }
+ void f2(C auto x) { called = 2; }
void f3(auto x) { called = 1; }
- void f3(C x) { called = 2; }
+ void f3(C auto x) { called = 2; }
};
template<C T>
struct S2 {
void f1(auto x) { called = 1; }
- void f2(C x) { called = 2; }
+ void f2(C auto x) { called = 2; }
void f3(auto x) { called = 1; }
- void f3(C x) { called = 2; }
+ void f3(C auto x) { called = 2; }
void h1(auto x);
- void h2(C x);
+ void h2(C auto x);
void h3(auto x);
- void h3(C x);
+ void h3(C auto x);
template<C U>
void g1(T t, U u) { called = 1; }
@@ -55,27 +55,27 @@ template<C T>
};
-void ptr(C*) { called = 1; }
-void ptr(const C*) { called = 2; }
+void ptr(C auto *) { called = 1; }
+void ptr(const C auto*) { called = 2; }
-void ref(C&) { called = 1; }
-void ref(const C&) { called = 2; }
+void ref(C auto &) { called = 1; }
+void ref(const C auto&) { called = 2; }
void
-fwd_lvalue_ref(Type&& x) {
+fwd_lvalue_ref(Type auto&& x) {
using T = decltype(x);
static_assert(std::is_lvalue_reference<T>::value, "not an lvlaue reference");
}
void
-fwd_const_lvalue_ref(Type&& x) {
+fwd_const_lvalue_ref(Type auto&& x) {
using T = decltype(x);
static_assert(std::is_lvalue_reference<T>::value, "not an lvalue reference");
using U = typename std::remove_reference<T>::type;
static_assert(std::is_const<U>::value, "not const-qualified");
}
-void fwd_rvalue_ref(Type&& x) {
+void fwd_rvalue_ref(Type auto&& x) {
using T = decltype(x);
static_assert(std::is_rvalue_reference<T>::value, "not an rvalue reference");
}
@@ -83,10 +83,10 @@ void fwd_rvalue_ref(Type&& x) {
// Make sure we can use nested names speicifers for concept names.
namespace N {
template<typename T>
- concept bool C() { return true; }
-} // namesspace N
+ concept C = true;
+} // namespace N
-void foo(N::C x) { }
+void foo(N::C auto x) { }
int main() {
S s;
@@ -138,19 +138,19 @@ int main() {
// Test that decl/def matching works.
void p(auto x) { called = 1; }
-void p(C x) { called = 2; }
+void p(C auto x) { called = 2; }
template<C T>
void S2<T>::h1(auto x) { called = 1; }
template<C T>
- void S2<T>::h2(C x) { called = 2; }
+ void S2<T>::h2(C auto x) { called = 2; }
template<C T>
void S2<T>::h3(auto x) { called = 1; }
template<C T>
- void S2<T>::h3(C x) { called = 2; }
+ void S2<T>::h3(C auto x) { called = 2; }
template<C T>
template<C U>
@@ -1,8 +1,8 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C = __is_class(T);
+ concept C = __is_class(T);
struct X { };
@@ -1,8 +1,8 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C() { return __is_class(T); }
+ concept C = __is_class(T);
template<typename T>
struct S1 {
@@ -1,39 +1,13 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C = __is_class(T);
+ concept C = __is_class(T);
-C{T} void f1();
+C{T} void f1(); // { dg-error "expected" }
struct S1
{
- C{T} void f2();
- C{T} static void f3();
+ C{T} void f2(); // { dg-error "expected" }
+ C{T} static void f3(); // { dg-error "expected" }
};
-
-int main()
-{
- S1 s;
-
- f1<S1>();
- s.f2<S1>();
- S1::f3<S1>();
-
- return 0;
-}
-
-template<typename T>
- void f1() requires C<T>
- {
- }
-
-template<typename T>
- void S1::f2() requires C<T>
- {
- }
-
-template<typename T>
- void S1::f3() requires C<T>
- {
- }
deleted file mode 100644
@@ -1,27 +0,0 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-#include <cassert>
-
-template<typename T>
- concept bool C() { return __is_class(T); }
-
-template<int N>
- concept bool P() { return true; }
-
-C{A} struct S1
-{
- P{B} int f1();
-};
-
-struct S2 {};
-
-int main()
-{
- S1<S2> s;
-
- assert(s.f1<10>() == sizeof(S2) + 10);
- return 0;
-}
-
-C{A} P{B} int S1<A>::f1() { return B + sizeof(A); }
deleted file mode 100644
@@ -1,18 +0,0 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template<typename ... T>
- concept bool C1 = true;
-
-template<int ... N>
- concept bool C2 = true;
-
-C1{...A} void f1() {};
-C2{...A} void f2() {};
-
-int main()
-{
- f1<int, short, char>();
- f2<1, 2, 3>();
- return 0;
-}
deleted file mode 100644
@@ -1,33 +0,0 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template<typename ... T>
- concept bool C1 = true;
-
-template<int ... N>
- concept bool C2 = true;
-
-template<typename T>
- concept bool C3 = __is_class(T);
-
-template<typename ... T>
- concept bool C4() { return true; }
-template<int N>
- concept bool C4() { return true; }
-
-template<typename T, typename U = int>
- concept bool C5() { return __is_class(U); }
-
-C1{...A, B} void f1() {}; // { dg-error "cannot deduce template parameters" }
-C1{A} void f2() {}
-C2{A, B} void f3() {};
-C3{...A} void f4() {}; // { dg-error "cannot be introduced" }
-C4{A} void f5() {}; // { dg-error "cannot deduce template parameters" }
-C5{A, B} void f6() {};
-
-int main()
-{
- // Defaults should not transfer
- f6<int>(); // { dg-error "no matching" }
- return 0;
-}
deleted file mode 100644
@@ -1,11 +0,0 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template<typename T, typename U = int>
- concept bool C()
- {
- return sizeof(U) == sizeof(int);
- }
-
-C{A} void f1() {} // { dg-error "all template parameters" }
-
deleted file mode 100644
@@ -1,13 +0,0 @@
-// PR c++/67003
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-namespace X {
- template<class>
- concept bool C = true;
-}
-
-X::C{T}
-void foo() {}
-
-int main() { foo<int>(); }
deleted file mode 100644
@@ -1,14 +0,0 @@
-// PR c++/66985
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
-
-template <template <class> class T>
-concept bool Valid = requires { typename T<int>; };
-
-template <template <class> class T>
-struct __defer { };
-
-Valid{T}
-struct __defer<T> {
- using type = T<int>;
-};
@@ -1,5 +1,6 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
+// { dg-prune-output "concept definition syntax is" }
struct S
{
@@ -1,20 +1,20 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool Type = true;
+ concept Type = true;
template<typename T, typename U>
- concept bool Same = __is_same_as(T, U);
+ concept Same = __is_same_as(T, U);
template<typename T, typename U>
- concept bool C1 = true;
+ concept C1 = true;
template<typename T, typename... Args>
- concept bool C2 = true;
+ concept C2 = true;
template<typename T, typename U>
- concept bool C3 = __is_same_as(T, int) && __is_same_as(U, double);
+ concept C3 = __is_same_as(T, int) && __is_same_as(U, double);
template<Same<int> T> struct S1 { };
template<typename T, Same<T> U> struct S2 { };
@@ -1,11 +1,11 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// Make sure that we check partial concept ids
// with variable concepts.
template<class A, class B>
-concept bool C = true;
+concept C = true;
template<C<int> D>
struct E
@@ -1,9 +1,9 @@
// PR c++/67138
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T>
-concept bool _Auto = true;
+concept _Auto = true;
template <_Auto T>
struct test {};
@@ -1,18 +1,18 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool C1 = sizeof(T) == 0;
+concept C1 = sizeof(T) == 0;
template<typename T, typename U>
-concept bool C2 = __is_same_as(T, U);
+concept C2 = __is_same_as(T, U);
template<typename T>
-concept bool D1 = requires (T t) { { t } -> C1; };
+concept D1 = requires (T t) { { t } -> C1; };
template<typename T>
-concept bool D2 = requires (T t) { { t } -> C2<void>; };
+concept D2 = requires (T t) { { t } -> C2<void>; };
void f1(auto D1) { } // OK: D1 is declared as a parameter
void f2(auto D2) { } // OK: D2 is declared as a parameter
@@ -1,12 +1,12 @@
// PR c++/66218
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T, class U>
-concept bool Same = __is_same_as(T, U);
+concept Same = __is_same_as(T, U);
template <class T>
-concept bool C =
+concept C =
requires { // { dg-message "in requirements" }
{ 0 } -> Same<T>; // { dg-message "does not satisfy" }
};
@@ -1,12 +1,12 @@
// PR c++/66218
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T, class U>
-concept bool Same = __is_same_as(T, U);
+concept Same = __is_same_as(T, U);
template <class T>
-concept bool C =
+concept C =
requires { // { dg-message "in requirements" }
{ 0 } -> Same<T>; // { dg-message "does not satisfy" }
};
@@ -1,12 +1,12 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T, class U>
-concept bool Same = __is_same_as(T, U);
+concept Same = __is_same_as(T, U);
const int i = 0;
template <class T>
-concept bool C =
+concept C =
requires {
{ &i } -> const Same<T>*; // { dg-error "not a plain type-constraint" }
};
@@ -1,8 +1,8 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <int I> struct B { static const int i = I; };
-template <int I> concept bool Few = I < 10;
+template <int I> concept Few = I < 10;
constexpr int g(B<Few> b); // { dg-error "does not constrain a type|invalid" }
@@ -1,20 +1,20 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool C1() {
- return requires () {
+concept C1 =
+ requires () {
{ T::smf() } noexcept;
};
-}
+
struct M1 {
static void smf() noexcept;
};
template<typename T>
-concept bool C2() {
- return C1<typename T::type>();
-}
+concept C2 =
+ C1<typename T::type>;
+
struct M2 {
using type = M1;
};
-static_assert(C2<M2>(), "");
+static_assert(C2<M2>, "");
@@ -1,11 +1,10 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
using TD = int;
template<typename T>
-concept bool C() {
- return requires () { typename TD; };
-}
+concept C =
+ requires () { typename TD; };
-static_assert(C<int>(), "");
+static_assert(C<int>, "");
@@ -1,26 +1,26 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool C = requires (T t) { t.mf(); };
+concept C = requires (T t) { t.mf(); };
template<typename T>
-concept bool CA1 = C<typename T::ca1_type>;
+concept CA1 = C<typename T::ca1_type>;
template<typename T>
-concept bool CA2 = CA1<T> && requires () { typename T::ca2_type; };
+concept CA2 = CA1<T> && requires () { typename T::ca2_type; };
template<typename T>
-concept bool CA3 = CA2<T> && requires () { typename T::ca3_type; };
+concept CA3 = CA2<T> && requires () { typename T::ca3_type; };
template<typename T>
-concept bool CB1 = requires () { typename T::cb1_type; };
+concept CB1 = requires () { typename T::cb1_type; };
template<typename T>
-concept bool CB2 = CB1<T> && requires () { typename T::cb2_type; };
+concept CB2 = CB1<T> && requires () { typename T::cb2_type; };
template<typename T>
-concept bool CB3 = CB2<T> && requires () { typename T::cb3_type; };
+concept CB3 = CB2<T> && requires () { typename T::cb3_type; };
struct MC { void mf(); };
@@ -1,65 +1,65 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// Performance test... This should be fast.
#include <type_traits>
template<typename T>
-concept bool Destructible() {
- return std::is_destructible<T>::value;
-}
+concept Destructible =
+ std::is_destructible<T>::value;
+
template<typename T, typename... Args>
-concept bool Constructible() {
- return Destructible<T>() && std::is_constructible<T, Args...>::value;
-}
+concept Constructible =
+ Destructible<T> && std::is_constructible<T, Args...>::value;
+
template<typename T>
-concept bool Move_constructible() {
- return Constructible<T, T&&>();
-}
+concept Move_constructible =
+ Constructible<T, T&&>;
+
template<typename T>
-concept bool Copy_constructible() {
- return Move_constructible<T>() && Constructible<T, const T&>();
-}
+concept Copy_constructible =
+ Move_constructible<T> && Constructible<T, const T&>;
+
template<typename T, typename U>
-concept bool Assignable() {
- return std::is_assignable<T, U>::value;
-}
+concept Assignable =
+ std::is_assignable<T, U>::value;
+
template<typename T>
-concept bool Move_assignable() {
- return Assignable<T&, T&&>();
-}
+concept Move_assignable =
+ Assignable<T&, T&&>;
+
template<typename T>
-concept bool Copy_assignable() {
- return Move_assignable<T>() && Assignable<T&, const T&>();
-}
+concept Copy_assignable =
+ Move_assignable<T> && Assignable<T&, const T&>;
+
template<typename T>
-concept bool Copyable() {
- return Copy_constructible<T>() && Copy_assignable<T>();
-}
+concept Copyable =
+ Copy_constructible<T> && Copy_assignable<T>;
+
template<typename T>
-concept bool C1() { return Copyable<T>(); }
+concept C1 = Copyable<T>;
template<typename T>
-concept bool C2() { return C1<T>(); }
+concept C2 = C1<T>;
template<typename T>
-concept bool C3() { return C2<T>(); }
+concept C3 = C2<T>;
template<typename T>
-concept bool C4() { return C3<T>(); }
+concept C4 = C3<T>;
template<typename T>
-concept bool C5() { return C4<T>(); }
+concept C5 = C4<T>;
template<typename T>
-concept bool C6() { return C5<T>(); }
+concept C6 = C5<T>;
template<typename T>
-concept bool C7() { return C6<T>(); }
+concept C7 = C6<T>;
template<typename T>
-concept bool C8() { return C7<T>(); }
+concept C8 = C7<T>;
template<typename T>
-concept bool C9() { return C8<T>(); }
+concept C9 = C8<T>;
template<typename T>
-concept bool C10() { return C9<T>(); }
+concept C10 = C9<T>;
template<typename T>
-concept bool C11() { return C10<T>(); }
+concept C11 = C10<T>;
struct S1 {};
struct S2 {};
@@ -68,9 +68,9 @@ struct S4 {};
struct S5 {};
struct S6 {};
-static_assert(C11<S1>(), "");
-static_assert(C11<S2>(), "");
-static_assert(C11<S3>(), "");
-static_assert(C11<S4>(), "");
-static_assert(C11<S5>(), "");
-static_assert(C11<S6>(), "");
+static_assert(C11<S1>, "");
+static_assert(C11<S2>, "");
+static_assert(C11<S3>, "");
+static_assert(C11<S4>, "");
+static_assert(C11<S5>, "");
+static_assert(C11<S6>, "");
@@ -1,6 +1,7 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template<class T> concept bool C1 = true;
+template<class T> concept C1 = true;
template<class A, class B> struct Pair {};
-void f(Pair<auto, C1>);
+// We used to test "Pair<auto, C1 >".
+void f(Pair<C1 auto, C1 auto>);
@@ -1,14 +1,15 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template <class X> concept bool allocatable = requires{{new X}->X *; };
-template <class X> concept bool semiregular = allocatable<X>;
-template <class X> concept bool readable = requires{requires semiregular<X>;};
+template<class T, class U> concept same_as = __is_same(T, U);
+template <class X> concept allocatable = requires{{new X}->same_as<X *>; };
+template <class X> concept semiregular = allocatable<X>;
+template <class X> concept readable = requires{requires semiregular<X>;};
template <class> int weak_input_iterator = requires{{0}->readable;};
template <class X> bool input_iterator{weak_input_iterator<X>}; // { dg-prune-output "narrowing conversion" }
template <class X> bool forward_iterator{input_iterator<X>};
template <class X> bool bidirectional_iterator{forward_iterator<X>};
template <class X>
-concept bool random_access_iterator{bidirectional_iterator<X>}; // { dg-error "constant" }
-void fn1(random_access_iterator);
+concept random_access_iterator = bidirectional_iterator<X>; // { dg-error "constant" }
+void fn1(random_access_iterator auto);
int main() { fn1(0); } // { dg-error "" }
@@ -1,22 +1,20 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class>
-concept bool C1 () {
- return true;
-}
+concept C1 = true;
+
template <class>
-concept bool C2 () {
- return true;
-}
+concept C2 = true;
+
template <class Expr>
-concept bool C3 () {
- return requires (Expr expr) {
+concept C3 =
+ requires (Expr expr) {
{expr}->C1;
{expr}->C2;
};
-}
-auto f (C3);
+
+auto f (C3 auto);
@@ -1,7 +1,7 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<template<typename> class T>
-concept bool C = T<int>::value;
+concept C = T<int>::value;
C c = 1; // { dg-error "does not constrain a type" }
@@ -1,10 +1,10 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool C() { return true; }
+concept bool C() { return true; } // { dg-error "the .bool. keyword" }
template bool C<int>(); // { dg-error "explicit instantiation of function concept" }
template<typename T>
-concept bool D = true;
+concept bool D = true; // { dg-error "the .bool. keyword" }
template bool D<int>; // { dg-error "explicit instantiation of variable concept" }
@@ -1,7 +1,7 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<template<typename> class T>
-concept bool C = true;
+concept C = true;
C c = 1; // { dg-error "does not constrain a type" }
@@ -1,13 +1,12 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<class T>
-concept bool Addable(){
- return requires(T x){
- {x + x} -> T;
+concept Addable =
+ requires(T x){
+ {x + x} -> T; // { dg-error "return-type-requirement is not a type-constraint" }
};
-}
int main(){
- Addable t = 0;
+ Addable auto t = 0;
}
@@ -1,6 +1,6 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template<int> concept bool C = true;
+template<int> concept C = true;
C c = 0; // { dg-error "does not constrain a type" }
@@ -1,8 +1,8 @@
// { dg-do compile { target c++17 } }
-// { dg-options "-fconcepts-ts" }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool foo() { return true; }; // { dg-message "declared here" }
+concept foo = true; // { dg-message "declared here" }
template<typename T>
void bar(T t)
@@ -1,13 +1,11 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool NameProvider()
-{
- return requires(){
+concept NameProvider =
+ requires(){
typename T::_name_t::template _member_t<int>;
};
-}
template<NameProvider... ColSpec>
void getTable(const ColSpec&...)
@@ -1,8 +1,8 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
// Conceptized version of template/ttp23.C
-template <class T> concept bool Foo = true;
+template <class T> concept Foo = true;
template <typename T> struct A {};
@@ -17,5 +17,5 @@ bool foo (const B<Q>& a);
void bar () {
B<A> a;
- foo (a);
+ foo (a); // { dg-error "call of overloaded" }
}
@@ -1,14 +1,14 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C1 = __is_same_as(T, int);
+ concept C1 = __is_same_as(T, int);
template<int N>
- concept bool C2 = N == 0;
+ concept C2 = N == 0;
template<template<typename> class X>
- concept bool C3 = false;
+ concept C3 = false;
template<typename> struct Foo;
@@ -16,9 +16,9 @@ template<typename> struct Foo;
// instantiation for the class.
template<C1 T = char> struct S1 { };
-template<C2 N = 1> struct S2 { };
-template<C3 X = Foo> struct S3 { };
+template<C2 N = 1> struct S2 { }; // { dg-error "does not constrain a type" }
+template<C3 X = Foo> struct S3 { }; // { dg-error "does not constrain a type|missing" }
S1<> s1; // { dg-error "constraint failure|invalid type" }
-S2<> s2; // { dg-error "constraint failure|invalid type" }
-S3<> s3; // { dg-error "constraint failure|invalid type" }
+S2<> s2; // { dg-error "constraint failure|invalid" }
+S3<> s3; // { dg-error "constraint failure|invalid" }
@@ -1,29 +1,29 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C1 = __is_same_as(T, int);
+ concept C1 = __is_same_as(T, int);
template<int N>
- concept bool C2 = N == 0;
+ concept C2 = N == 0;
template<template<typename> class X>
- concept bool C3 = true;
+ concept C3 = true;
template<typename> struct Foo;
template<C1...> struct S1;
template<C1... Ts> struct S1 { };
-template<C2...> struct S2;
-template<C2... Ns> struct S2 { };
+template<C2...> struct S2; // { dg-error "does not constrain a type" }
+template<C2... Ns> struct S2 { }; // { dg-error "does not constrain a type" }
-template<C3...> struct S3;
-template<C3... Xs> struct S3 { };
+template<C3...> struct S3; // { dg-error "does not constrain a type" }
+template<C3... Xs> struct S3 { }; // { dg-error "does not constrain a type" }
S1<int, int, int> s1; // OK
S1<> s11;
S2<0, 0, 0> s2;
-S2<> s22;
-S3<Foo, Foo> s3;
-S3<> s33;
+S2<> s22; // { dg-error "" }
+S3<Foo, Foo> s3; // { dg-error "" }
+S3<> s33; // { dg-error "" }
@@ -1,21 +1,21 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C1 = __is_same_as(T, int);
+ concept C1 = __is_same_as(T, int);
template<int N>
- concept bool C2 = N == 0;
+ concept C2 = N == 0;
template<template<typename> class X>
- concept bool C3 = false;
+ concept C3 = false;
template<typename> struct Foo;
template<C1... Ts> struct S1 { };
-template<C2... Ns> struct S2 { };
-template<C3... Xs> struct S3 { };
+template<C2... Ns> struct S2 { }; // { dg-error "does not constrain a type" }
+template<C3... Xs> struct S3 { }; // { dg-error "does not constrain a type" }
S1<int, int, bool> s1; // { dg-error "constraint failure|invalid type" }
-S2<0, 1, 2> s2; // { dg-error "constraint failure|invalid type" }
-S3<Foo> s3; // { dg-error "constraint failure|invalid type" }
+S2<0, 1, 2> s2; // { dg-error "wrong number of template arguments" }
+S3<Foo> s3;
@@ -1,6 +1,6 @@
// PR c++/66937
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
#include <tuple>
@@ -23,13 +23,11 @@ using copy_tuple_args = typename detail::copy_tuple_args_impl<Tuple, Sink>::type
// A concept of a column
template <typename T>
-concept bool Column()
-{
- return requires()
+concept Column =
+ requires()
{
typename T::_name_t;
};
-}
// column_list is constrained to Column arguments
template<Column... C>
@@ -1,19 +1,19 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
-concept bool C1 = __is_class(T);
+concept C1 = __is_class(T);
template<typename T>
-concept bool C2 = requires (T t) { t; };
+concept C2 = requires (T t) { t; };
-void f1(C1, C1) { }
+void f1(C1 auto, C1 auto) { }
template<typename T>
requires C2<T>
void f2(T) { }
-void f3(C2) { }
+void f3(C2 auto) { }
struct S1 {};
@@ -1,14 +1,14 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C1 = __is_class(T);
+ concept C1 = __is_class(T);
template<typename U>
requires C1<U>
void f1(U, U) { }
-void f2(C1) {}
+void f2(C1 auto) {}
int main ()
{
@@ -1,22 +1,22 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T>
- concept bool C1 = __is_class(T);
+ concept C1 = __is_class(T);
template<typename T>
- concept bool C2() { return __is_class(T); }
+ concept C2 = __is_class(T);
template<typename T>
constexpr bool C3 = __is_class(T);
template<typename U>
- requires C1<U>() // { dg-error "cannot call a concept" }
+ requires C1<U>
void f1(U) { }
template<typename U>
- requires C2<U> // { dg-error "must be called" }
+ requires C2<U>
void f2(U) { }
template<C3 T> // { dg-error "not a type" }
@@ -1,20 +1,20 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T, typename U>
-concept bool Same = __is_same_as(T, U);
+concept Same = __is_same_as(T, U);
template<typename T0, typename T1, typename T2, typename... T3toN>
-concept bool Same<T0, T1, T2, T3toN...> = true; // { dg-error "wrong number|does not match" }
+concept Same<T0, T1, T2, T3toN...> = true; // { dg-error "expected" }
template<typename T>
-concept bool C1 = true;
+concept C1 = true;
template<typename T>
-concept bool C1<T*> = true; // { dg-error "specialization of variable concept" }
+concept C1<T*> = true; // { dg-error "expected" }
template<typename T>
-concept bool C2 = true;
+concept C2 = true;
template<>
-concept bool C2<int> = true; // { dg-error "non-template variable" }
+concept C2<int> = true; // { dg-error "concept definition syntax|expected|type" }
@@ -1,11 +1,11 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename T1, typename T2>
-concept bool C1 = true;
+concept C1 = true;
template<typename T1, typename T2, typename T3>
-concept bool C2 = true;
+concept C2 = true;
template<C1 T> // { dg-error "wrong number of template arguments" }
@@ -1,5 +1,5 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T>
-concept int C = true; // { dg-error "bool" }
+concept int C = true; // { dg-error "concept definition syntax" }
@@ -1,9 +1,13 @@
// PR c++/85133
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template<typename> concept bool C; // { dg-error "no initializer" }
+/* The error with "concept bool" used to be "variable concept has no
+ initializer" which is much better. Let's at least test that we
+ do not crash. */
-template<C...> struct A {};
+template<typename> concept C; // { dg-error "expected" }
-A<int> a;
+template<C...> struct A {}; // { dg-error "declared" }
+
+A<int> a; // { dg-error "" }
@@ -1,5 +1,5 @@
// PR c++/67117
-// { dg-do compile { target c++17_only } }
+// { dg-do compile { target c++17 } }
// { dg-options "-fconcepts" }
template <class T>
@@ -1,18 +1,17 @@
// PR c++/67139
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T>
constexpr typename T::type::value_type _v = T::type::value;
-template <class T> concept bool IsTrue_() { return _v<T>; }
+template <class T> concept IsTrue_ = _v<T>;
-template <class T> concept bool Unpossible() {
- return IsTrue_<T &&>();
-}
+template <class T> concept Unpossible =
+ IsTrue_<T &&>;
template <class> constexpr bool unpossible() { return false; }
-Unpossible{ T }
+template<Unpossible T>
constexpr bool unpossible() { return true; }
static_assert((!unpossible<void>()), "");
@@ -1,6 +1,6 @@
// PR c++/68666
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
struct A {
template <class>
@@ -8,6 +8,7 @@ struct A {
};
template <class T>
-concept bool C = A::val<T>;
+concept C = A::val<T>;
-C{T} struct B {};
+template<C T>
+struct B {};
@@ -1,9 +1,9 @@
// PR c++/66712
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template <class T, class...Args>
-concept bool _Constructible_ =
+concept _Constructible_ =
requires (Args&&...args)
{
T{ ((Args&&)(args))... };
@@ -12,7 +12,8 @@ concept bool _Constructible_ =
template <class T, class...Args>
constexpr bool _constructible_() { return false; }
-_Constructible_{T, ...Args}
+template<typename T, typename... Args>
+ requires _Constructible_<T, Args...>
constexpr bool _constructible_() { return true; }
struct S
@@ -1,9 +1,9 @@
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template <class T> concept bool Copyable = requires (T t) { T(t); };
-template <class T> concept bool Constructable = requires { T(); };
-template <class T> concept bool Both = Copyable<T> && Constructable<T>;
+template <class T> concept Copyable = requires (T t) { T(t); };
+template <class T> concept Constructable = requires { T(); };
+template <class T> concept Both = Copyable<T> && Constructable<T>;
template <Copyable... Ts> // requires (Copyable<Ts> && ...)
constexpr int f(Ts...) { return 0; } // #1
@@ -1,8 +1,8 @@
// PR c++/70036
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
-template <class T> concept bool C = true;
+template <class T> concept C = true;
template <class... T>
void f(T...) requires C<T>; // { dg-error "parameter pack" }
@@ -1,11 +1,11 @@
// PR c++/73456
-// { dg-do compile { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
template<typename...> struct list {};
template<typename Seq>
-concept bool Sequence = true;
+concept Sequence = true;
template<Sequence... Seqs> // requires (Sequence<Seqs> && ...)
struct zip;
@@ -1,16 +1,16 @@
// PR c++/65575
-// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-fconcepts" }
template<typename T>
-concept bool C = false;
+concept C = false;
-int f1() requires false;
-int& f2() requires false;
-int* f3() requires false;
-auto f4() -> int& requires false;
-auto f5() -> int* requires false;
-auto f6() -> int requires false;
+int f1() requires false; // { dg-error "constraints on a non-templated function" }
+int& f2() requires false; // { dg-error "constraints on a non-templated function" }
+int* f3() requires false; // { dg-error "constraints on a non-templated function" }
+auto f4() -> int& requires false; // { dg-error "constraints on a non-templated function" }
+auto f5() -> int* requires false; // { dg-error "constraints on a non-templated function" }
+auto f6() -> int requires false; // { dg-error "constraints on a non-templated function" }
int (*p1)() requires true; // { dg-error "" }
int (&p2)() requires true; // { dg-error "" }
@@ -19,5 +19,5 @@ int g(int (*)() requires true); // { dg-error "" }
int
main()
{
- f1(); // { dg-error "" }
+ f1();
}
@@ -1,21 +1,19 @@
// PR c++/66091
-// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-fconcepts" }
template<typename T>
-concept bool C1()
-{
- return requires() { typename T::type1; };
-}
+concept C1 =
+ requires() { typename T::type1; };
+
template<typename T>
-concept bool C2()
-{
- return C1<T>() && requires() { typename T::type2; };
-}
+concept C2 =
+ C1<T> && requires() { typename T::type2; };
+
template<C1 T>
struct S {
S& operator++() { return *this; }
- S& operator++() requires C2<T>() { return *this; }
+ S& operator++() requires (C2<T>) { return *this; }
};
@@ -1,6 +1,6 @@
// PR c++/67148
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
namespace std
{
@@ -58,9 +58,9 @@ struct all_same<T, Rest...> :
meta::and_c<__is_same_as(T, Rest)...> {};
}
template <class...Ts>
-concept bool Same() {
- return detail::all_same<Ts...>::value;
-}
+concept Same =
+ detail::all_same<Ts...>::value;
+
template <class F, class...Args>
using ResultType = decltype(declval<F>()(declval<Args>()...));
template <class>
@@ -74,35 +74,39 @@ using ValueType =
typename value_type<T>::type;
template <class F, class...Args>
-concept bool Function() {
- return requires (F& f, Args&&...args) {
+concept Function =
+ requires (F& f, Args&&...args) {
f((Args&&)args...);
- requires Same<decltype(f((Args&&)args...)), ResultType<F, Args...> >();
+ requires Same<decltype(f((Args&&)args...)), ResultType<F, Args...> >;
};
-}
+
template <class, class...> struct __function : std::false_type {};
-Function{F, ...Args} struct __function<F, Args...> : std::true_type {};
+template<typename F, typename... Args>
+ requires Function<F, Args...>
+struct __function<F, Args...> : std::true_type {};
template <class F, class I1, class I2>
-concept bool IndirectCallable() {
- return Function<F, ValueType<I1>, ValueType<I2>>();
-}
+concept IndirectCallable =
+ Function<F, ValueType<I1>, ValueType<I2>>;
+
template <class F, class I1, class I2>
-concept bool IndirectCallable2() {
- return __function<F, ValueType<I1>, ValueType<I2>>::value;
-}
+concept IndirectCallable2 =
+ __function<F, ValueType<I1>, ValueType<I2>>::value;
+
namespace ext { namespace models {
template <class, class, class>
constexpr bool indirect_callable() { return false; }
-IndirectCallable{F, I1, I2}
+template<typename F, typename I1, typename I2>
+ requires IndirectCallable<F, I1, I2>
constexpr bool indirect_callable() { return true; }
template <class, class, class>
constexpr bool indirect_callable2() { return false; }
-IndirectCallable2{F, I1, I2}
+template<typename F, typename I1, typename I2>
+ requires IndirectCallable<F, I1, I2>
constexpr bool indirect_callable2() { return true; }
}}
}}
@@ -1,25 +1,20 @@
// PR c++/67225
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <class T, class U>
-concept bool Same()
-{
- return true;
-}
+concept Same = true;
template <class T> struct WrapT {T t;};
template <class T>
-concept bool Destructible()
-{
- return requires(T t, const T ct, WrapT<T>& wt) // { dg-message "in requirements" }
+concept Destructible =
+ requires(T t, const T ct, WrapT<T>& wt) // { dg-message "in requirements" }
{
{wt.~WrapT()} noexcept;
// {&t} -> Same<T*>; // #1
//{&t} -> T*; // #2
};
-}
template <Destructible T>
void f() {}
@@ -1,21 +1,19 @@
// PR c++/67225
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename Target>
// template<typename Target, typename... Ts>
-concept bool has_resize ()
-{
- return requires (Target tgt)
+concept has_resize =
+ requires (Target tgt)
{
{ tgt.resize () };
};
-}
template<typename Target>
void resize (Target tgt)
{
- if constexpr (has_resize<Target> ())
+ if constexpr (has_resize<Target>)
{
tgt.resize ();
}
@@ -1,9 +1,9 @@
// PR c++/67225
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <class>
-concept bool Dummy = true;
+concept Dummy = true;
template <typename>
class example {
@@ -1,12 +1,12 @@
// PR c++/67225
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <class, class>
-concept bool C1 = true;
+concept C1 = true;
template <class>
-concept bool C2 = requires { { 42 } -> C1<int>; };
+concept C2 = requires { { 42 } -> C1<int>; };
int main() {
class A { int x; } a;
@@ -1,12 +1,12 @@
// PR c++/67225
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename A, typename T>
-concept bool SomeConcept = true;
+concept SomeConcept = true;
template <typename T>
-void breaker(SomeConcept<int>);
+void breaker(SomeConcept<int> auto);
class SomeClass {
int privateMember;
@@ -1,12 +1,10 @@
// PR c++/67319
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <typename T>
-concept bool Any()
-{
- return requires (T t) { +t; };
-}
+concept Any =
+ requires (T t) { +t; };
struct my_struct
{
@@ -1,16 +1,17 @@
// PR c++/67427
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <class S, class I>
-concept bool Sentinel =
+concept Sentinel =
requires (I i) { i; };
template <class I, class S>
-concept bool SizedIteratorRange =
+concept SizedIteratorRange =
Sentinel<S, I> && true;
-Sentinel{S, I}
+template<typename S, typename I>
+ requires Sentinel<S, I>
void distance(I first, S last) {}
template <class I, class S>
@@ -1,6 +1,6 @@
// PR c++/67427
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <bool... Values> struct and_c_impl {
static constexpr bool value = true;
@@ -15,13 +15,11 @@ template <bool... Values> constexpr bool and_c() {
return and_c_impl<Values...>::value;
}
-template<class T> concept bool C() {
- return true;
-}
+template<class T> concept C = true;
template<class... Tx>
struct A {
- A() requires and_c<C<Tx>()...>() = default;
+ A() requires (and_c<C<Tx>...>()) = default;
};
int main() {
@@ -1,10 +1,10 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
-template<class T> concept bool C1() { return false; }
-template<C1 T> concept bool C2() { return true; } // { dg-error "cannot be constrained" }
+template<class T> concept C1 = false;
+template<C1 T> concept C2 = true; // { dg-error "cannot be constrained" }
-void f(C2 x) {
+void f(C2 auto x) {
}
struct A {} a;
@@ -1,52 +1,52 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<class T>
class A {
public:
template<int I, class S>
- requires I > 0
+ requires (I > 0)
friend int f1(const A<S>&);
template<int I, class S>
- friend int f2(const A<S>&) requires I > 0;
+ friend int f2(const A<S>&) requires (I > 0);
private:
int x = 2;
};
template<int I, class S>
- requires I > 0
+ requires (I > 0)
int f1(const A<S>& a) {
return a.x;
}
template<int I, class S>
-int f2(const A<S>& a) requires I > 0 {
+int f2(const A<S>& a) requires (I > 0) {
return a.x;
}
class B {
public:
template<int I>
- requires I > 0
+ requires (I > 0)
friend int f3(const B&);
template<int I>
- friend int f4(const B&) requires I > 0;
+ friend int f4(const B&) requires (I > 0);
private:
int x = 2;
};
template<int I>
- requires I > 0
+ requires (I > 0)
int f3(const B& a) {
return a.x;
}
template<int I>
-int f4(const B& a) requires I > 0 {
+int f4(const B& a) requires (I > 0) {
return a.x;
}
@@ -1,15 +1,14 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<class X>
-concept bool C() {
- return requires(X x, bool b) {
+concept C =
+ requires(X x, bool b) {
requires b; // { dg-error "not a constant expression" }
x++;
};
-}
int main() {
- C<int>();
+ C<int>;
return 0;
}
@@ -1,9 +1,8 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
-template<class X> concept bool C() {
- return __is_same_as(X, int) || __is_same_as(X, long);
-}
+template<class X> concept C =
+ __is_same_as(X, int) || __is_same_as(X, long);
template<C... Tx>
struct Ax {};
@@ -1,13 +1,12 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
#include <type_traits>
#include <utility>
#include <iostream>
-template <class X> concept bool cpt_RealScalar() {
- return std::is_floating_point<X>::value;
-}
+template <class X> concept cpt_RealScalar =
+ std::is_floating_point<X>::value;
namespace detail {
template <class, class> constexpr bool k_evaluator_impl = false;
@@ -16,7 +15,7 @@ template <std::size_t... Indexes, class E>
constexpr bool k_evaluator_impl<std::index_sequence<Indexes...>, E> = true;
}
-template <class X, std::size_t K> concept bool cpt_KEvaluator =
+template <class X, std::size_t K> concept cpt_KEvaluator =
detail::k_evaluator_impl<std::make_index_sequence<K>, X>;
int main() {
@@ -1,5 +1,5 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
struct A {
template <class T>
@@ -8,13 +8,12 @@ struct A {
}
};
-template <class X> concept bool C() {
- return requires {
+template <class X> concept C =
+ requires {
&X::operator();
};
-}
int main() {
- static_assert(!C<A>());
+ static_assert(!C<A>);
return 0;
}
@@ -1,5 +1,5 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
#include <type_traits>
@@ -15,11 +15,11 @@ template <class... Operands> constexpr bool and_(Operands... operands) {
return and_impl(operands...);
}
-template <class X> concept bool C() { return true; }
+template <class X> concept C = true;
// v1
template<int, class... Xs>
- requires and_(C<Xs>()...)
+ requires (and_(C<Xs>...))
constexpr int f(const Xs&... xs) {
return 0;
}
@@ -38,10 +38,10 @@ int main() {
// 2nd example
template <typename T, typename... Us>
-concept bool AreType() {
- return (std::is_same<T,Us>::value && ...);
+concept AreType =
+ (std::is_same<T,Us>::value && ...);
// return true; gives the same overloaded error
-}
+
// Function with constraint
template<typename T, AreType<T>... Us>
@@ -1,5 +1,5 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
typedef int size_t;
template <typename _Tp> struct A { static constexpr _Tp value = 1; };
@@ -22,31 +22,29 @@ using make_index_sequence = make_integer_sequence<size_t, _Num>;
template <bool...> struct and_c_impl { static constexpr bool value = true; };
template <bool...> constexpr bool and_c() { return and_c_impl<>::value; }
-template <class X, class Y> concept bool cpt_Convertible() {
- return is_convertible<X, Y>::value;
-}
+template <class X, class Y> concept cpt_Convertible =
+ is_convertible<X, Y>::value;
template <class T> using uncvref_t = typename remove_reference<T>::type;
struct Plus;
using index_t = int;
template <class> bool cpt_Index;
template <class... Extents>
-requires and_c<cpt_Index<Extents>()...>() class Dimensionality;
+requires (and_c<cpt_Index<Extents>()...>()) class Dimensionality;
namespace detail_concept {
template <class> bool match_dimensionality;
template <class... Extents>
constexpr bool match_dimensionality<Dimensionality<Extents...>> = true;
}
-template <class X> concept bool cpt_Dimensionality() {
- return detail_concept::match_dimensionality<X>;
-}
+template <class X> concept cpt_Dimensionality =
+ detail_concept::match_dimensionality<X>;
-template <class X> concept bool cpt_Shaped() { return requires(X x){{x};}; }
+template <class X> concept cpt_Shaped = requires(X x){{x};};
-template <class X> concept bool cpt_Dimensioned() { return cpt_Shaped<X>(); }
+template <class X> concept cpt_Dimensioned = cpt_Shaped<X>;
template <class... Extents>
-requires and_c<cpt_Index<Extents>()...>() class Dimensionality {
+requires (and_c<cpt_Index<Extents>()...>()) class Dimensionality {
public:
static constexpr size_t num_dimensions = sizeof...(Extents);
};
@@ -64,26 +62,22 @@ requires requires(Functor functor, Expressibles... expressibles) {
decltype(auto) map_impl(Functor, Expressibles...);
void cpt_ContinualScalar();
-template <class> concept bool cpt_Scalar() { return cpt_ContinualScalar; }
+template <class> concept cpt_Scalar = cpt_ContinualScalar;
-template <class X> concept bool cpt_FlatEvaluator() {
- return requires(X x){{x}->cpt_Scalar;};
-}
+template <class X> concept cpt_FlatEvaluator =
+ requires(X x){{x}->cpt_Scalar;};
template <class, class> bool k_evaluator_impl;
template <size_t... Indexes, class Evaluator>
constexpr bool k_evaluator_impl<index_sequence<Indexes...>, Evaluator> = true;
-template <class X, size_t K> concept bool cpt_KEvaluator() {
- return k_evaluator_impl<make_index_sequence<K>, X>;
-}
+template <class X, size_t K> concept cpt_KEvaluator =
+ k_evaluator_impl<make_index_sequence<K>, X>;
-template <class X, size_t K> concept bool cpt_KCompatibleEvaluator() {
- return cpt_KEvaluator<X, K>();
-}
+template <class X, size_t K> concept cpt_KCompatibleEvaluator =
+ cpt_KEvaluator<X, K>;
-template <class X> concept bool cpt_Structure() {
- return cpt_Convertible<X, base>();
-}
+template <class X> concept cpt_Structure =
+ cpt_Convertible<X, base>;
template <cpt_Dimensionality Dimensionality, cpt_Structure,
cpt_KCompatibleEvaluator<Dimensionality::num_dimensions> Evaluator>
@@ -99,9 +93,8 @@ constexpr bool match_numeric_array_expression<
NumericArrayExpression<Dimensionality, Structure, Evaluator>> = true;
}
-template <class X> concept bool cpt_NumericArrayExpression() {
- return detail_concept::match_numeric_array_expression<X>;
-}
+template <class X> concept cpt_NumericArrayExpression =
+ detail_concept::match_numeric_array_expression<X>;
namespace expression_traits {
namespace detail_expression_traits {
@@ -138,7 +131,7 @@ auto make_numeric_array_expression(Dimensionality dimensionality,
template <size_t, class Functor, class... Evaluators>
auto make_map_evaluator_impl(Functor) requires
- and_(cpt_FlatEvaluator<Evaluators>()...);
+ (and_(cpt_FlatEvaluator<Evaluators>...));
template <class Functor, class... Expressions>
requires
requires(Expressions... expressions,
@@ -149,14 +142,13 @@ requires(Expressions... expressions,
}
decltype(auto) map_expressions_impl(Functor, Expressions...);
-template <class Functor, class... Expressibles> concept bool cpt_Mappable() {
- return requires(Functor functor, Expressibles... expressibles) {
+template <class Functor, class... Expressibles> concept cpt_Mappable =
+ requires(Functor functor, Expressibles... expressibles) {
map_impl(functor, expressibles...);
};
-}
void ____C_A_T_C_H____T_E_S_T____8() {
auto e1 = make_numeric_array_expression<general>(DimensionalityC<>(), [] {});
using E1 = decltype(e1);
- cpt_Mappable<Plus, E1>();
+ cpt_Mappable<Plus, E1>;
}
@@ -1,5 +1,5 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <class, class>
class NumericArray {};
@@ -10,21 +10,19 @@ constexpr bool
match_numeric_array<NumericArray<Scalar, Shape>> =
true;
template <class T>
-concept bool cpt_NumericArrayContainer() {
- return match_numeric_array<T>;
-}
+concept cpt_NumericArrayContainer =
+ match_numeric_array<T>;
template <class X>
-concept bool cpt_NumericArray() {
- return requires{requires cpt_NumericArrayContainer<X>();};
-}
+concept cpt_NumericArray =
+ requires{requires cpt_NumericArrayContainer<X>;};
template <class X>
-requires !cpt_NumericArray<X>() auto func(int, X) {}
+requires (!cpt_NumericArray<X>) auto func(int, X) {}
template <class X>
-requires cpt_NumericArray<X>() auto func(int, X) {}
+requires (cpt_NumericArray<X>) auto func(int, X) {}
int main() {
NumericArray<double, int> v5;
@@ -1,12 +1,12 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template <class T>
-concept bool True = true;
+concept True = true;
template <class T>
struct S {
- friend bool operator==(S, int) requires True<T> { return true; }
- friend bool operator==(S, int) requires !True<T> { return true; }
+ friend bool operator==(S, int) requires (True<T>) { return true; }
+ friend bool operator==(S, int) requires (!True<T>) { return true; }
};
int main() {
@@ -1,14 +1,13 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename F>
-concept bool FCallable()
-{
- return requires(F)
+concept FCallable =
+ requires(F)
{
F::f();
};
-}
+
class Test1
{
@@ -26,7 +25,7 @@ public:
static void f() {}
};
-template<typename X> concept bool C = true;
+template<typename X> concept C = true;
template<C... X>
void bar(X...)
@@ -1,5 +1,5 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
namespace zero
{
@@ -18,7 +18,7 @@ namespace zero
namespace one
{
- template<typename X, typename Y> concept bool Foo = true;
+ template<typename X, typename Y> concept Foo = true;
template<typename... T>
struct foo
@@ -1,36 +1,34 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename T>
-concept bool Boolean()
-{
- return requires(T t)
+concept Boolean =
+ requires(T t)
{
- { t } -> bool;
+ { t } -> bool; // { dg-error "return-type-requirement is not a type-constraint" }
};
-}
+
template<typename T>
-concept bool C()
-{
- return requires (T t)
+concept C =
+ requires (T t)
{
{ t } -> Boolean;
};
-}
+
template<typename T>
struct X;
template<typename T>
- requires ! C<typename T::type>()
+ requires (! C<typename T::type>)
struct X<T>
{
using type = int;
};
template<typename T>
- requires C<typename T::type>()
+ requires C<typename T::type>
struct X<T>
{
using type = int;
@@ -1,14 +1,14 @@
-// { dg-do compile { target c++2a } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-fconcepts" }
template <class T, class U>
-concept bool Same = __is_same(T, U);
+concept Same = __is_same(T, U);
struct test {
- void func(Same<int>... ints) {}
+ void func(Same<int> auto... ints) {}
};
-void func(Same<int>... ints) {}
+void func(Same<int> auto... ints) {}
int main()
{
@@ -1,10 +1,10 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
#include <type_traits>
template <class T, class U>
-concept bool Same = std::is_same<T, U>::value;
+concept Same = std::is_same<T, U>::value;
struct test {
template <Same<int>... Ints>
@@ -1,7 +1,7 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename T, T N>
-concept bool C0() { return true; }
+concept C0 = true;
-void f(C0<0>);
+void f(C0<0>); // { dg-error "declared void|wrong number" }
@@ -1,8 +1,8 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename T, typename T::type>
-concept bool C = true;
+concept C = true;
template<C<0> T> class ct {};
@@ -1,14 +1,13 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename F>
-concept bool FCallable()
-{
- return requires(F)
+concept FCallable =
+ requires(F)
{
F::f();
};
-}
+
class Test1
{
@@ -1,11 +1,11 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<class I>
-concept bool True = true;
+concept True = true;
template<class T>
-concept bool HasType = requires { typename T::type; };
+concept HasType = requires { typename T::type; };
template<class T>
struct S
@@ -1,8 +1,8 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<class T>
-concept bool C = requires(const T& t) { t.foo(); };
+concept C = requires(const T& t) { t.foo(); };
template<class T>
struct Base
@@ -1,4 +1,4 @@
-// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-fconcepts" }
-template<T> concept bool C = true; // { dg-error "has not been declared" }
+template<T> concept C = true; // { dg-error "has not been declared" }
deleted file mode 100644
@@ -1,7 +0,0 @@
-// PR c++/85265
-// { dg-do compile { target c++17_only } }
-// { dg-additional-options "-fconcepts-ts" }
-
-template<typename> concept bool C = true;
-
-C{} void foo(); // { dg-error "expected identifier" }
@@ -1,5 +1,5 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
namespace X
{
@@ -9,7 +9,7 @@ namespace X
template<int> using helper = void;
template<typename T>
-concept bool C =
+concept C =
requires
{
requires X::x<T>;
@@ -1,9 +1,9 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
#include <type_traits>
template<typename t2, typename t = std::remove_reference_t<t2>>
-concept bool IntegralOrIntegralRef = std::is_integral_v<t>;
+concept IntegralOrIntegralRef = std::is_integral_v<t>;
template<IntegralOrIntegralRef t>
auto foo(t && v)
@@ -1,10 +1,10 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
template<typename X, typename Y = X>
-concept bool HasBinaryAdd = requires(X x, Y y)
+concept HasBinaryAdd = requires(X x, Y y)
{
- {x + y} -> decltype(x + y);
+ {x + y} -> decltype(x + y); // { dg-error "return-type-requirement is not a type-constraint" }
};
-void proc(HasBinaryAdd x, HasBinaryAdd y);
+void proc(HasBinaryAdd auto x, HasBinaryAdd auto y);
@@ -1,15 +1,15 @@
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
-
-// Test conversion requirements (not in C++20)
+// { dg-additional-options "-fconcepts -fconcepts-diagnostics-depth=2" }
// req9.C
+template<class T, class U> concept same_as = __is_same(T, U);
+
template<typename T>
struct S1 { };
template<typename T>
-concept C = requires(T x) { { x.fn() } -> S1<T>; };
+concept C = requires(T x) { { x.fn() } -> same_as<S1<T>>; };
template<typename U>
requires C<U>
@@ -33,7 +33,7 @@ int driver_1()
// Test implicit conversion requirements
template<typename T, typename U>
-concept ConvertibleTo = requires(T& t) { {t} -> U&; }; // { dg-error "inaccessible" }
+concept ConvertibleTo = requires(T& t) { {t} -> U&; }; // { dg-error "inaccessible|return-type-requirement" }
struct B { };
class D : /*private*/ B { };
deleted file mode 100644
@@ -1,49 +0,0 @@
-// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
-
-// This tests the terse notation.
-
-template<typename T>
-concept True = true;
-
-template<typename T>
-concept False = false;
-
-template<typename T, typename U>
-concept SameAs = __is_same_as(T, U);
-
-True x1 = 0;
-False x2 = 0; // { dg-error "deduced initializer does not satisfy" }
-
-void f1(True t) { }
-void f2(False t) { }
-void f3(SameAs<int> q) { }
-void f4(True a, SameAs<decltype(a)> b) { }
-
-True f5() { return 0; }
-False f6() { return 0; } // { dg-error "deduced return type" }
-SameAs<int> f7() { return 0; }
-SameAs<int> f8() { return 'a'; } // { dg-error "deduced return type" }
-auto f9() -> True { return 0; }
-auto f10() -> False { return 0; } // { dg-error "deduced return type" }
-auto f11() -> SameAs<int> { return 0; }
-auto f12() -> SameAs<char> { return 0; } // { dg-error "deduced return type" }
-auto f13(int n) -> SameAs<decltype(n)> { return n; }
-auto f14(int n) -> SameAs<decltype(n)> { return 'a'; } // { dg-error "deduced return type" }
-auto f15(auto x) -> SameAs<decltype(x)> { return 0; } // { dg-error "deduced return type" }
-
-void driver()
-{
- f1(0);
- f2(0); // { dg-error "" }
- f3(0);
- f3('a'); // { dg-error "" }
- f4(0, 0);
- f4(0, 'a'); // { dg-error "" }
- f15(0); // { dg-bogus "" }
- f15('a'); // { dg-message "" }
-}
-
-template<class T> concept bool C1() { return false; }
-template<C1 T> concept bool C2() { return true; } // { dg-error "cannot be constrained" }
-template<C1 T> concept bool C3 = true; // { dg-error "cannot be constrained" }
deleted file mode 100644
@@ -1,260 +0,0 @@
-// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
-
-// Basic tests using function concepts.
-
-template<typename T>
-concept bool Type() { return true; }
-
-template<typename T>
-concept bool False() { return false; }
-
-template<typename T>
-concept bool Class() { return __is_class(T); }
-
-template<typename T>
-concept bool EmptyClass() { return Class<T>() && __is_empty(T); }
-
-template<typename T, typename U>
-concept bool Classes() { return __is_class(T) && __is_class (U); }
-
-struct empty { };
-
-struct nonempty { int n; };
-
-static_assert(Type<int>());
-static_assert(False<int>()); // { dg-error "static assertion failed" }
-
-// Basic checks
-
-template<typename T>
- requires (Type<T>())
-int fn1(T t) { return 0; }
-
-template<typename T>
- requires (False<T>())
-int fn2(T t) { return 0; }
-
-void driver()
-{
- fn1(0); // OK
- fn2(0); // { dg-error "" }
-}
-
-// Ordering
-
-template<typename T>
-concept bool Cf() { return requires (T t) { t.f(); }; }
-
-template<typename T>
-concept bool Cfg() { return Cf<T>() && requires (T t) { t.g(); }; }
-
-template<typename T>
-concept bool Cf2() { return requires (T t) { t.f(); }; }
-
-template<typename T>
-constexpr int algo(T t) { return 0; }
-
-template<typename T> requires (Cf<T>())
-constexpr int algo(T t) { return 1; }
-
-template<typename T> requires (Cfg<T>())
-constexpr int algo(T t) { return 2; }
-
-template<typename T> requires (Cf<T>())
-constexpr int ambig(T t) { return 1; }
-
-template<typename T> requires (Cf2<T>())
-constexpr int ambig(T t) { return 1; }
-
-struct T1 {
- void f() { }
-};
-
-struct T2 : T1 {
- void g() { }
-};
-
-void driver_0()
-{
- T1 x;
- T2 y;
- static_assert(algo(0) == 0);
- static_assert(algo(x) == 1);
- static_assert(algo(y) == 2);
- ambig(x); // { dg-error "call of overload | is ambiguous" }
-}
-
-template<typename T>
-struct S
-{
- void f() requires (Class<T>()) { }
-
- template<typename U>
- struct Inner
- {
- void g() requires (Classes<T, U>()) { }
- };
-
- template<typename U> requires (Classes<T, U>()) void h(U) { }
-};
-
-struct X { };
-
-void driver_1()
-{
- S<X> s1;
- s1.f(); // OK
- s1.h(s1); // OK
- s1.h(0); // { dg-error "no matching function" }
-
- S<int> s2;
- s2.f(); // { dg-error "no matching function" }
-
- S<X>::Inner<X> si1;
- si1.g();
-
- S<X>::Inner<int> si2;
- si2.g(); // { dg-error "no matching function" }
-}
-
-// Check constraints on non-dependent arguments, even when in a
-// dependent context.
-
-template<typename T> requires (Class<T>()) void f1(T x) { }
-
-// fn1-2.C -- Dependent checks
-template<typename T>
-void caller_1(T x)
-{
- f1(x); // Unchecked dependent arg.
- f1(empty{}); // Checked non-dependent arg, but OK
- f1(0); // { dg-error "" }
-}
-
-// fn3.c -- Ordering
-template<typename T>
- requires (Class<T>())
-constexpr int f2(T x) { return 1; }
-
-template<typename T>
- requires (EmptyClass<T>())
-constexpr int f2(T x) { return 2; }
-
-template<typename T>
-constexpr int f3(T x) requires (Class<T>()) { return 1; }
-
-template<typename T>
-constexpr int f3(T x) requires (EmptyClass<T>()) { return 2; }
-
-void driver_2()
-{
- f2(0); // { dg-error "no matching function" }
- static_assert (f2(empty{}) == 2);
- static_assert (f2(nonempty{}) == 1);
- f3(0); // { dg-error "no matching function" }
- static_assert (f3(empty{}) == 2);
- static_assert (f3(nonempty{}) == 1);
-}
-
-// fn8.C -- Address of overloaded functions
-template<typename T> requires (Type<T>()) void ok(T) { }
-template<typename T> requires (Class<T>()) void err(T) { }
-
-auto p1 = &ok<int>;
-auto p2 = &err<int>; // { dg-error "" }
-void (*p3)(int) = &ok<int>;
-void (*p4)(int) = &err<int>; // { dg-error "no matches" }
-void (*p5)(int) = &ok;
-void (*p6)(int) = &err; // { dg-error "no matches" }
-
-template<typename T> void g(T x) { }
-
-void driver_3 ()
-{
- g(&ok<int>);
- g(&err<int>); // { dg-error "no match" }
-}
-
-
-struct S2 {
- template<typename T> requires (Type<T>()) int ok(T) { return 0; }
- template<typename T> requires (Class<T>()) int err(T) { return 0; }
-};
-
-auto p7 = &S2::ok<int>;
-auto p8 = &S2::err<int>; // { dg-error "" }
-int (S2::*p9)(int) = &S2::ok<int>;
-int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
-int (S2::*p11)(int) = &S2::ok;
-int (S2::*p12)(int) = &S2::err; // { dg-error "no matches" }
-
-// fn9.C -- Ordering with function address
-template<typename T>
- requires (Class<T>())
-constexpr int fn(T) { return 1; }
-
-template<typename T>
- requires (EmptyClass<T>())
-constexpr int fn(T) { return 2; }
-
-struct S3
-{
- template<typename T>
- requires (Class<T>())
- constexpr int fn(T) const { return 1; }
-
- template<typename T>
- requires (EmptyClass<T>())
- constexpr int fn(T) const { return 2; }
-};
-
-void driver_5 () {
- struct X { };
- struct Y { X x; };
-
- constexpr X x;
- constexpr Y y;
- constexpr S3 s;
-
- constexpr auto p1 = &fn<X>; // Empty f
- static_assert (p1(x) == 2);
-
- constexpr auto p2 = &fn<Y>; // Class f
- static_assert(p2(y) == 1);
-
- constexpr auto p3 = &S3::fn<X>; // Empty f
- static_assert((s.*p3)(x) == 2);
-
- constexpr auto p4 = &S3::fn<Y>; // Empty f
- static_assert((s.*p4)(y) == 1);
-}
-
-
-// Redeclarations
-
-// FIXME: This should be a diagnosable error. The programmer has moved
-// the requirements from the template-head to the declarator.
-template<typename T> requires (Type<T>()) void f3();
-template<typename T> void f3() requires (Type<T>());
-
-void driver_4()
-{
- f3<int>(); // { dg-error "call of overload | ambiguous" }
-}
-
-template<template<typename T> requires true class X> void f4();
-template<template<typename T> class X> void f4(); // OK: different declarations
-
-template<typename T> requires (Type<T>()) void def() { }
-template<typename T> requires (Type<T>()) void def() { } // { dg-error "redefinition" }
-
-// fn-concept1.C
-
-template<typename T>
-concept bool Tuple() { // { dg-error "multiple statements" }
- static_assert(T::value, "");
- return true;
-}
-
-void f(Tuple&);
deleted file mode 100644
@@ -1,251 +0,0 @@
-// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
-
-// Basic tests using variable concepts.
-
-template<typename T>
-concept bool Type = true;
-
-template<typename T>
-concept bool False = false;
-
-template<typename T>
-concept bool Class = __is_class(T);
-
-template<typename T>
-concept bool EmptyClass = Class<T> && __is_empty(T);
-
-template<typename T, typename U>
-concept bool Classes = __is_class(T) && __is_class (U);
-
-struct empty { };
-
-struct nonempty { int n; };
-
-static_assert(Type<int>);
-static_assert(False<int>); // { dg-error "static assertion failed" }
-
-// Basic checks
-
-template<typename T>
- requires Type<T>
-int fn1(T t) { return 0; }
-
-template<typename T>
- requires False<T>
-int fn2(T t) { return 0; }
-
-void driver()
-{
- fn1(0); // OK
- fn2(0); // { dg-error "" }
-}
-
-// Ordering
-
-template<typename T>
-concept bool Cf = requires (T t) { t.f(); };
-
-template<typename T>
-concept bool Cfg = Cf<T> && requires (T t) { t.g(); };
-
-template<typename T>
-concept bool Cf2 = requires (T t) { t.f(); };
-
-template<typename T>
-constexpr int algo(T t) { return 0; }
-
-template<typename T> requires Cf<T>
-constexpr int algo(T t) { return 1; }
-
-template<typename T> requires Cfg<T>
-constexpr int algo(T t) { return 2; }
-
-template<typename T> requires Cf<T>
-constexpr int ambig(T t) { return 1; }
-
-template<typename T> requires Cf2<T>
-constexpr int ambig(T t) { return 1; }
-
-struct T1 {
- void f() { }
-};
-
-struct T2 : T1 {
- void g() { }
-};
-
-void driver_0()
-{
- T1 x;
- T2 y;
- static_assert(algo(0) == 0);
- static_assert(algo(x) == 1);
- static_assert(algo(y) == 2);
- ambig(x); // { dg-error "call of overload | is ambiguous" }
-}
-
-template<typename T>
-struct S
-{
- void f() requires Class<T> { }
-
- template<typename U>
- struct Inner
- {
- void g() requires Classes<T, U> { }
- };
-
- template<typename U> requires Classes<T, U> void h(U) { }
-};
-
-struct X { };
-
-void driver_1()
-{
- S<X> s1;
- s1.f(); // OK
- s1.h(s1); // OK
- s1.h(0); // { dg-error "no matching function" }
-
- S<int> s2;
- s2.f(); // { dg-error "no matching function" }
-
- S<X>::Inner<X> si1;
- si1.g();
-
- S<X>::Inner<int> si2;
- si2.g(); // { dg-error "no matching function" }
-}
-
-// Check constraints on non-dependent arguments, even when in a
-// dependent context.
-
-template<typename T> requires Class<T> void f1(T x) { }
-
-// fn1-2.C -- Dependent checks
-template<typename T>
-void caller_1(T x)
-{
- f1(x); // Unchecked dependent arg.
- f1(empty{}); // Checked non-dependent arg, but OK
- f1(0); // { dg-error "" }
-}
-
-// fn3.c -- Ordering
-template<typename T>
- requires Class<T>
-constexpr int f2(T x) { return 1; }
-
-template<typename T>
- requires EmptyClass<T>
-constexpr int f2(T x) { return 2; }
-
-template<typename T>
-constexpr int f3(T x) requires Class<T> { return 1; }
-
-template<typename T>
-constexpr int f3(T x) requires EmptyClass<T> { return 2; }
-
-void driver_2()
-{
- f2(0); // { dg-error "no matching function" }
- static_assert (f2(empty{}) == 2);
- static_assert (f2(nonempty{}) == 1);
- f3(0); // { dg-error "no matching function" }
- static_assert (f3(empty{}) == 2);
- static_assert (f3(nonempty{}) == 1);
-}
-
-// fn8.C -- Address of overloaded functions
-template<typename T> requires Type<T> void ok(T) { }
-template<typename T> requires Class<T> void err(T) { }
-
-auto p1 = &ok<int>;
-auto p2 = &err<int>; // { dg-error "" }
-void (*p3)(int) = &ok<int>;
-void (*p4)(int) = &err<int>; // { dg-error "no matches" }
-void (*p5)(int) = &ok;
-void (*p6)(int) = &err; // { dg-error "no matches" }
-
-template<typename T> void g(T x) { }
-
-void driver_3 ()
-{
- g(&ok<int>);
- g(&err<int>); // { dg-error "no match" }
-}
-
-
-struct S2 {
- template<typename T> requires Type<T> int ok(T) { return 0; }
- template<typename T> requires Class<T> int err(T) { return 0; }
-};
-
-auto p7 = &S2::ok<int>;
-auto p8 = &S2::err<int>; // { dg-error "" }
-int (S2::*p9)(int) = &S2::ok<int>;
-int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
-int (S2::*p11)(int) = &S2::ok;
-int (S2::*p12)(int) = &S2::err; // { dg-error "no matches" }
-
-// fn9.C -- Ordering with function address
-template<typename T>
- requires Class<T>
-constexpr int fn(T) { return 1; }
-
-template<typename T>
- requires EmptyClass<T>
-constexpr int fn(T) { return 2; }
-
-struct S3
-{
- template<typename T>
- requires Class<T>
- constexpr int fn(T) const { return 1; }
-
- template<typename T>
- requires EmptyClass<T>
- constexpr int fn(T) const { return 2; }
-};
-
-void driver_5 () {
- struct X { };
- struct Y { X x; };
-
- constexpr X x;
- constexpr Y y;
- constexpr S3 s;
-
- constexpr auto p1 = &fn<X>; // Empty f
- static_assert (p1(x) == 2);
-
- constexpr auto p2 = &fn<Y>; // Class f
- static_assert(p2(y) == 1);
-
- constexpr auto p3 = &S3::fn<X>; // Empty f
- static_assert((s.*p3)(x) == 2);
-
- constexpr auto p4 = &S3::fn<Y>; // Empty f
- static_assert((s.*p4)(y) == 1);
-}
-
-
-// Redeclarations
-
-// FIXME: This should be a diagnosable error. The programmer has moved
-// the requirements from the template-head to the declarator.
-template<typename T> requires Type<T> void f3();
-template<typename T> void f3() requires Type<T>;
-
-void driver_4()
-{
- f3<int>(); // { dg-error "call of overload | ambiguous" }
-}
-
-template<template<typename T> requires true class X> void f4();
-template<template<typename T> class X> void f4(); // OK: different declarations
-
-template<typename T> requires Type<T> void def() { }
-template<typename T> requires Type<T> void def() { } // { dg-error "redefinition" }
-
deleted file mode 100644
@@ -1,36 +0,0 @@
-// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
-
-// Basic tests for introduction syntax.
-
-template<typename T>
-concept True = true;
-
-template<typename T>
-concept False = false;
-
-template<typename T, typename U>
-concept Same = __is_same_as(T, U);
-
-template<int N>
-concept Pos = N >= 0;
-
-True{T} void f1(T) { }
-False{T} void f2(T) { }
-Same{X, Y} void same();
-Pos{N} void fn();
-
-void driver()
-{
- f1(0);
- f2(0); // { dg-error "" }
-
- same<int, int>();
- same<int, char>(); // { dg-error "" }
-
- fn<0>(); // OK
- fn<-1>(); // { dg-error "" }
- fn<int>(); // { dg-error "no matching function" }
- // { dg-error "type/value mismatch at argument 1" "" { target *-*-* } .-1 }
- // { dg-message "expected a constant of type .int., got .int." "" { target *-*-* } .-2 }
-}
deleted file mode 100644
@@ -1,10 +0,0 @@
-// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
-
-struct Base {
- template<typename T>
- static concept bool D() { return __is_same_as(T, int); } // { dg-error "a concept cannot be a member function" }
-
- template<typename T, typename U>
- static concept bool E() { return __is_same_as(T, U); } // { dg-error "a concept cannot be a member function" }
-};
deleted file mode 100644
@@ -1,74 +0,0 @@
-// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
-
-template<typename T, int N, typename... Xs> concept bool C1 = true;
-
-template<template<typename> class X> concept bool C2 = true;
-
-template<typename... Ts> concept bool C3 = true;
-
-C1{A, B, ...C} struct S1 { };
-
-C2{T} void f();
-
-C2{...Ts} void g(); // { dg-error "cannot be introduced" }
-
-C3{...Ts} struct S2 { };
-C3{T, U, V} struct S3 { };
-C3{...Ts, U} struct S4 { }; // { dg-error "cannot deduce template parameters" }
-
-template<typename> struct X { };
-
-void driver1() {
- S1<int, 0, char, bool, float> s1a;
- S1<0, 0, char, bool, float> s1b; // { dg-error "type/value mismatch" }
-
- f<X>();
- f<int>(); // { dg-error "no matching function for call" }
- // { dg-error "type/value mismatch at argument 1" "" { target *-*-* } .-1 }
- // { dg-message "expected a class template, got .int." "" { target *-*-* } .-2 }
-
- S2<int> s2a;
- S2<char, signed char, unsigned char> s2b;
- S2<0> s2c; // { dg-error "type/value mismatch" }
-
- S3<int, int, int> s3a;
- S3<int, int> s3b; // { dg-error "wrong number of template arguments" }
-}
-
-template<typename... Args>
-struct all_same;
-
-template<typename T, typename U, typename... Args>
-struct all_same<T, U, Args...>
-{
- static constexpr bool value = __is_same_as(T, U) && all_same<U, Args...>::value;
-};
-
-template<typename T>
-struct all_same<T>
-{
- static constexpr bool value = true;
-};
-
-template<>
-struct all_same<>
-{
- static constexpr bool value = true;
-};
-
-template<typename... Ts>
-concept AllSame = all_same<Ts...>::value;
-
-AllSame{...Ts} struct S5 { };
-AllSame{T, U} struct S6 { };
-
-void driver2()
-{
- S5<int, int> s5a;
- S5<int, int, int, int> s5b;
- S5<int, int, int, char> s5c; // { dg-error "template constraint failure" }
- S6<void, void> s6a;
- S6<void, int> s6c; // { dg-error "template constraint failure" }
- S6<void, void, void> s6b; // { dg-error "wrong number of template arguments" }
-}
@@ -1,5 +1,5 @@
// PR c++/102933
// { dg-do compile { target c++20 } }
-// { dg-additional-options "-fconcepts-ts" }
+// { dg-additional-options "-fconcepts" }
#include "nontype-class50.C"
@@ -1,6 +1,6 @@
-// { dg-options "-fconcepts-ts" }
// { dg-do compile { target c++20 } }
+// This used to be:
// PR testsuite/101782
// attribute-specifier-seq cannot follow requires-clause with -fconcepts-ts