diff options
author | Marek Polacek <polacek@redhat.com> | 2024-05-31 08:54:00 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2024-07-10 15:38:48 -0400 |
commit | f0fb6b6acd805cfd3197eaf78d5404fa45759727 (patch) | |
tree | d4c1002b3f5535a2d4640b6e5d96a6c6638f8827 | |
parent | 0c27eade4754c13a54e265e4305182c95be1e441 (diff) | |
download | gcc-f0fb6b6acd805cfd3197eaf78d5404fa45759727.zip gcc-f0fb6b6acd805cfd3197eaf78d5404fa45759727.tar.gz gcc-f0fb6b6acd805cfd3197eaf78d5404fa45759727.tar.bz2 |
c++: remove Concepts TS code
In GCC 14 we deprecated Concepts TS and discussed removing the code
in GCC 15. This patch removes Concepts TS code from the front end,
including support for template-introductions, as in:
template<typename T>
concept C = true;
C{T} void foo (T); // write template<C T> void foo (T);
The biggest part of this patch is adjusting the testsuite. We don't
want to lose coverage so I've converted most of -fconcepts-ts tests
to C++20. That means they no longer have to be c++17_only. Mostly
this meant turning "concept bool" into "concept" and turning function
concepts into C++20 concepts. I've added missing "auto"s where
required, but "auto"s in template-argument-lists are not supported
anymore so I've removed some of the tests; some of them are still
present to verify we don't crash on such autos. I've also added ()
around "requires" expressions.
I plan to add a porting_to.html entry with a few hints.
I've rebased and tested the patch after the recent r15-1103.
gcc/c-family/ChangeLog:
* c-cppbuiltin.cc (c_cpp_builtins): Remove flag_concepts_ts code.
* c-opts.cc (c_common_post_options): Likewise.
* c.opt: Remove -fconcepts-ts.
* c.opt.urls: Regenerate.
gcc/cp/ChangeLog:
* constraint.cc (deduce_concept_introduction, get_deduced_wildcard,
get_introduction_prototype, introduce_type_template_parameter,
introduce_template_template_parameter,
introduce_nontype_template_parameter,
build_introduced_template_parameter, introduce_template_parameter,
introduce_template_parameter_pack, introduce_template_parameter,
introduce_template_parameters, process_introduction_parms,
check_introduction_list, finish_template_introduction): Remove.
(finish_shorthand_constraint): Remove a Concepts TS comment.
* cp-tree.h (check_auto_in_tmpl_args, finish_template_introduction):
Remove.
* decl.cc (function_requirements_equivalent_p): Remove pre-C++20 code.
(grokfndecl): Don't check flag_concepts_ts.
(grokvardecl): Don't check that concept have type bool.
* parser.cc (cp_parser_decl_specifier_seq): Don't check
flag_concepts_ts.
(cp_parser_introduction_list): Remove.
(cp_parser_template_id): Remove dead code.
(cp_parser_simple_type_specifier): Don't check flag_concepts_ts.
(cp_parser_placeholder_type_specifier): Require require auto or
decltype(auto) even pre-C++20. Don't check flag_concepts_ts.
(cp_parser_type_id_1): Don't check flag_concepts_ts.
(cp_parser_template_type_arg): Likewise.
(cp_parser_requires_clause_opt): Remove flag_concepts_ts code.
(cp_parser_compound_requirement): Don't check flag_concepts_ts.
(cp_parser_template_introduction): Remove.
(cp_parser_template_declaration_after_export): Don't call
cp_parser_template_introduction.
* pt.cc (template_heads_equivalent_p): Remove pre-C++20 code.
(find_parameter_pack_data): Remove type_pack_expansion_p.
(find_parameter_packs_r): Remove flag_concepts_ts code. Remove
type_pack_expansion_p code.
(uses_parameter_packs): Remove type_pack_expansion_p code.
(make_pack_expansion): Likewise.
(check_for_bare_parameter_packs): Likewise.
(fixed_parameter_pack_p): Likewise.
(tsubst_qualified_id): Remove dead code.
(extract_autos_r): Remove.
(extract_autos): Remove.
(do_auto_deduction): Remove flag_concepts_ts code.
(type_uses_auto): Likewise.
(check_auto_in_tmpl_args): Remove.
gcc/ChangeLog:
* doc/invoke.texi: Mention that -fconcepts-ts was removed.
libstdc++-v3/ChangeLog:
* testsuite/std/ranges/access/101782.cc: Don't compile with
-fconcepts-ts.
gcc/testsuite/ChangeLog:
* g++.dg/concepts/auto3.C: Compile with -fconcepts. Run in C++17 and
up. Add dg-error.
* g++.dg/concepts/auto5.C: Likewise.
* g++.dg/concepts/auto7.C: Compile with -fconcepts. Add dg-error.
* g++.dg/concepts/auto8a.C: Compile with -fconcepts.
* g++.dg/concepts/class-deduction1.C: Compile with -fconcepts. Run in
C++17 and up. Convert to C++20.
* g++.dg/concepts/class5.C: Likewise.
* g++.dg/concepts/class6.C: Likewise.
* g++.dg/concepts/debug1.C: Likewise.
* g++.dg/concepts/decl-diagnose.C: Compile with -fconcepts. Run in
C++17 and up. Add dg-error.
* g++.dg/concepts/deduction-constraint1.C: Compile with -fconcepts.
Run in C++17 and up. Convert to C++20.
* g++.dg/concepts/diagnostic1.C: Likewise.
* g++.dg/concepts/dr1430.C: Likewise.
* g++.dg/concepts/equiv.C: Likewise.
* g++.dg/concepts/equiv2.C: Likewise.
* g++.dg/concepts/expression.C: Likewise.
* g++.dg/concepts/expression2.C: Likewise.
* g++.dg/concepts/expression3.C: Likewise.
* g++.dg/concepts/fn-concept2.C: Compile with -fconcepts. Run in
C++17 and up. Remove code. Add dg-prune-output.
* g++.dg/concepts/fn-concept3.C: Compile with -fconcepts. Run in
C++17 and up. Convert to C++20.
* g++.dg/concepts/fn1.C: Likewise.
* g++.dg/concepts/fn10.C: Likewise.
* g++.dg/concepts/fn2.C: Likewise.
* g++.dg/concepts/fn3.C: Likewise.
* g++.dg/concepts/fn4.C: Likewise.
* g++.dg/concepts/fn5.C: Likewise.
* g++.dg/concepts/fn6.C: Likewise.
* g++.dg/concepts/fn7.C: Compile with -fconcepts. Add dg-error.
* g++.dg/concepts/fn8.C: Compile with -fconcepts. Run in C++17 and up.
Convert to C++20.
* g++.dg/concepts/fn9.C: Likewise.
* g++.dg/concepts/generic-fn-err.C: Likewise.
* g++.dg/concepts/generic-fn.C: Likewise.
* g++.dg/concepts/inherit-ctor1.C: Likewise.
* g++.dg/concepts/inherit-ctor3.C: Likewise.
* g++.dg/concepts/intro1.C: Likewise.
* g++.dg/concepts/locations1.C: Compile with -fconcepts. Run in C++17
and up. Add dg-prune-output.
* g++.dg/concepts/partial-concept-id1.C: Compile with -fconcepts.
Run in C++17 and up. Convert to C++20.
* g++.dg/concepts/partial-concept-id2.C: Likewise.
* g++.dg/concepts/partial-spec5.C: Likewise.
* g++.dg/concepts/placeholder2.C: Likewise.
* g++.dg/concepts/placeholder3.C: Likewise.
* g++.dg/concepts/placeholder4.C: Likewise.
* g++.dg/concepts/placeholder5.C: Likewise.
* g++.dg/concepts/placeholder6.C: Likewise.
* g++.dg/concepts/pr65634.C: Likewise.
* g++.dg/concepts/pr65636.C: Likewise.
* g++.dg/concepts/pr65681.C: Likewise.
* g++.dg/concepts/pr65848.C: Likewise.
* g++.dg/concepts/pr67249.C: Likewise.
* g++.dg/concepts/pr67595.C: Likewise.
* g++.dg/concepts/pr68434.C: Likewise.
* g++.dg/concepts/pr71127.C: Likewise.
* g++.dg/concepts/pr71128.C: Compile with -fconcepts. Run in C++17
and up. Add dg-error.
* g++.dg/concepts/pr71131.C: Compile with -fconcepts. Run in C++17
and up. Convert to C++20.
* g++.dg/concepts/pr71385.C: Likewise.
* g++.dg/concepts/pr85065.C: Likewise.
* g++.dg/concepts/pr92804-2.C: Compile with -fconcepts. Convert to
C++20.
* g++.dg/concepts/template-parm11.C: Compile with -fconcepts. Run in
C++17 and up. Convert to C++20.
* g++.dg/concepts/template-parm12.C: Likewise.
* g++.dg/concepts/template-parm2.C: Likewise.
* g++.dg/concepts/template-parm3.C: Likewise.
* g++.dg/concepts/template-parm4.C: Likewise.
* g++.dg/concepts/template-template-parm1.C: Likewise.
* g++.dg/concepts/var-concept1.C: Likewise.
* g++.dg/concepts/var-concept2.C: Likewise.
* g++.dg/concepts/var-concept3.C: Likewise.
* g++.dg/concepts/var-concept4.C: Likewise.
* g++.dg/concepts/var-concept5.C: Likewise.
* g++.dg/concepts/var-concept6.C: Likewise.
* g++.dg/concepts/var-concept7.C: Likewise.
* g++.dg/concepts/var-templ1.C: Run in C++17 and up.
* g++.dg/concepts/var-templ2.C: Compile with -fconcepts. Run in C++17
and up. Convert to C++20.
* g++.dg/concepts/var-templ3.C: Likewise.
* g++.dg/concepts/variadic1.C: Likewise.
* g++.dg/concepts/variadic2.C: Likewise.
* g++.dg/concepts/variadic3.C: Likewise.
* g++.dg/concepts/variadic4.C: Likewise.
* g++.dg/cpp2a/concepts-pr65575.C: Likewise.
* g++.dg/cpp2a/concepts-pr66091.C: Likewise.
* g++.dg/cpp2a/concepts-pr67148.C: Compile with -fconcepts. Convert
to C++20.
* g++.dg/cpp2a/concepts-pr67225-1.C: Likewise.
* g++.dg/cpp2a/concepts-pr67225-2.C: Likewise.
* g++.dg/cpp2a/concepts-pr67225-3.C: Likewise.
* g++.dg/cpp2a/concepts-pr67225-4.C: Likewise.
* g++.dg/cpp2a/concepts-pr67225-5.C: Likewise.
* g++.dg/cpp2a/concepts-pr67319.C: Likewise.
* g++.dg/cpp2a/concepts-pr67427.C: Likewise.
* g++.dg/cpp2a/concepts-pr67654.C: Likewise.
* g++.dg/cpp2a/concepts-pr67658.C: Likewise.
* g++.dg/cpp2a/concepts-pr67684.C: Likewise.
* g++.dg/cpp2a/concepts-pr67697.C: Likewise.
* g++.dg/cpp2a/concepts-pr67719.C: Likewise.
* g++.dg/cpp2a/concepts-pr67774.C: Likewise.
* g++.dg/cpp2a/concepts-pr67825.C: Likewise.
* g++.dg/cpp2a/concepts-pr67860.C: Likewise.
* g++.dg/cpp2a/concepts-pr67862.C: Likewise.
* g++.dg/cpp2a/concepts-pr67969.C: Likewise.
* g++.dg/cpp2a/concepts-pr68093-2.C: Likewise.
* g++.dg/cpp2a/concepts-pr68372.C: Likewise.
* g++.dg/cpp2a/concepts-pr68812.C: Likewise.
* g++.dg/cpp2a/concepts-pr69235.C: Likewise.
* g++.dg/cpp2a/concepts-pr78752-2.C: Likewise.
* g++.dg/cpp2a/concepts-pr78752.C: Likewise.
* g++.dg/cpp2a/concepts-pr79759.C: Likewise.
* g++.dg/cpp2a/concepts-pr80746.C: Likewise.
* g++.dg/cpp2a/concepts-pr80773.C: Likewise.
* g++.dg/cpp2a/concepts-pr82507.C: Likewise.
* g++.dg/cpp2a/concepts-pr82740.C: Likewise.
* g++.dg/cpp2a/concepts-pr84980.C: Compile with -fconcepts. Run in
C++17 and up. Convert to C++20.
* g++.dg/cpp2a/concepts-pr85265.C: Likewise.
* g++.dg/cpp2a/concepts-pr85808.C: Compile with -fconcepts. Convert
to C++20.
* g++.dg/cpp2a/concepts-pr86269.C: Likewise.
* g++.dg/cpp2a/concepts-pr87441.C: Likewise.
* g++.dg/cpp2a/concepts-requires5.C: Compile with -fconcepts.
Adjust dg-error. Add same_as.
* g++.dg/cpp2a/nontype-class50a.C: Compile with -fconcepts.
* g++.dg/concepts/auto1.C: Removed.
* g++.dg/concepts/auto4.C: Removed.
* g++.dg/concepts/auto6.C: Removed.
* g++.dg/concepts/fn-concept1.C: Removed.
* g++.dg/concepts/intro2.C: Removed.
* g++.dg/concepts/intro3.C: Removed.
* g++.dg/concepts/intro4.C: Removed.
* g++.dg/concepts/intro5.C: Removed.
* g++.dg/concepts/intro6.C: Removed.
* g++.dg/concepts/intro7.C: Removed.
* g++.dg/cpp2a/concepts-ts1.C: Removed.
* g++.dg/cpp2a/concepts-ts2.C: Removed.
* g++.dg/cpp2a/concepts-ts3.C: Removed.
* g++.dg/cpp2a/concepts-ts4.C: Removed.
* g++.dg/cpp2a/concepts-ts5.C: Removed.
* g++.dg/cpp2a/concepts-ts6.C: Removed.
141 files changed, 712 insertions, 2313 deletions
diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index dfd8f6f..a80372c 100644 --- a/gcc/c-family/c-cppbuiltin.cc +++ b/gcc/c-family/c-cppbuiltin.cc @@ -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"); diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index b7789b7..7d21033 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -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) diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 864ef4e..5c1006f 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -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) diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls index 31d9ffe..1b60ae4 100644 --- a/gcc/c-family/c.opt.urls +++ b/gcc/c-family/c.opt.urls @@ -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) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index ebf4255..5472cc5 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -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? */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4bb3e9c..f270b0b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7490,7 +7490,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); @@ -8592,7 +8591,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); diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 2961610..d4c65a1 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -1017,16 +1017,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. */ @@ -10661,9 +10651,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"); @@ -11366,9 +11355,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"); diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 31ae9c2..6bf3f52 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -16624,16 +16624,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 @@ -18431,61 +18430,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. */ @@ -19218,16 +19162,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); @@ -20549,10 +20485,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 " @@ -20895,10 +20830,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, @@ -20929,38 +20861,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 @@ -20978,9 +20901,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). */ @@ -25245,14 +25166,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); @@ -25326,7 +25244,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; @@ -31618,8 +31536,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) @@ -31704,10 +31621,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); } /*--------------------------------------------------------------------------- @@ -32082,7 +31996,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"); @@ -33228,110 +33142,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 @@ -33423,8 +33233,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; } diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index d131648..e38e024 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -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); @@ -17355,15 +17328,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); @@ -29629,63 +29593,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_"; @@ -31227,16 +31134,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, @@ -31448,66 +31348,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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 4d671c4..4850c73 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3228,8 +3228,8 @@ 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. +in GCC 14 and removed in GCC 15; users are expected to convert their code +to C++20 concepts. @opindex fconstexpr-depth @item -fconstexpr-depth=@var{n} diff --git a/gcc/testsuite/g++.dg/concepts/auto1.C b/gcc/testsuite/g++.dg/concepts/auto1.C deleted file mode 100644 index abf7886..0000000 --- a/gcc/testsuite/g++.dg/concepts/auto1.C +++ /dev/null @@ -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 "" } diff --git a/gcc/testsuite/g++.dg/concepts/auto3.C b/gcc/testsuite/g++.dg/concepts/auto3.C index 868a56c..5c91cc0 100644 --- a/gcc/testsuite/g++.dg/concepts/auto3.C +++ b/gcc/testsuite/g++.dg/concepts/auto3.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/auto4.C b/gcc/testsuite/g++.dg/concepts/auto4.C deleted file mode 100644 index 6c98455..0000000 --- a/gcc/testsuite/g++.dg/concepts/auto4.C +++ /dev/null @@ -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(); -} diff --git a/gcc/testsuite/g++.dg/concepts/auto5.C b/gcc/testsuite/g++.dg/concepts/auto5.C index f1d653e..5538f2e 100644 --- a/gcc/testsuite/g++.dg/concepts/auto5.C +++ b/gcc/testsuite/g++.dg/concepts/auto5.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/auto6.C b/gcc/testsuite/g++.dg/concepts/auto6.C deleted file mode 100644 index 1f6d72e..0000000 --- a/gcc/testsuite/g++.dg/concepts/auto6.C +++ /dev/null @@ -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>(); diff --git a/gcc/testsuite/g++.dg/concepts/auto7.C b/gcc/testsuite/g++.dg/concepts/auto7.C index 3cbf5dd..26c9e9e 100644 --- a/gcc/testsuite/g++.dg/concepts/auto7.C +++ b/gcc/testsuite/g++.dg/concepts/auto7.C @@ -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>()); diff --git a/gcc/testsuite/g++.dg/concepts/auto8a.C b/gcc/testsuite/g++.dg/concepts/auto8a.C index fc60dc8..f4b0d96 100644 --- a/gcc/testsuite/g++.dg/concepts/auto8a.C +++ b/gcc/testsuite/g++.dg/concepts/auto8a.C @@ -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; diff --git a/gcc/testsuite/g++.dg/concepts/class-deduction1.C b/gcc/testsuite/g++.dg/concepts/class-deduction1.C index 7f427d0..5d4b149 100644 --- a/gcc/testsuite/g++.dg/concepts/class-deduction1.C +++ b/gcc/testsuite/g++.dg/concepts/class-deduction1.C @@ -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 diff --git a/gcc/testsuite/g++.dg/concepts/class5.C b/gcc/testsuite/g++.dg/concepts/class5.C index 5f8ece9..02d670e 100644 --- a/gcc/testsuite/g++.dg/concepts/class5.C +++ b/gcc/testsuite/g++.dg/concepts/class5.C @@ -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> diff --git a/gcc/testsuite/g++.dg/concepts/class6.C b/gcc/testsuite/g++.dg/concepts/class6.C index a1c5e16..77f7203 100644 --- a/gcc/testsuite/g++.dg/concepts/class6.C +++ b/gcc/testsuite/g++.dg/concepts/class6.C @@ -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 { }; diff --git a/gcc/testsuite/g++.dg/concepts/debug1.C b/gcc/testsuite/g++.dg/concepts/debug1.C index fb48567..43af419 100644 --- a/gcc/testsuite/g++.dg/concepts/debug1.C +++ b/gcc/testsuite/g++.dg/concepts/debug1.C @@ -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; diff --git a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C index 96038fd..0d10ce1 100644 --- a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C +++ b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C @@ -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 } }; diff --git a/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C b/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C index d510fe0..4350f59 100644 --- a/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C +++ b/gcc/testsuite/g++.dg/concepts/deduction-constraint1.C @@ -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); diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic1.C b/gcc/testsuite/g++.dg/concepts/diagnostic1.C index 207c36c..2f299b3 100644 --- a/gcc/testsuite/g++.dg/concepts/diagnostic1.C +++ b/gcc/testsuite/g++.dg/concepts/diagnostic1.C @@ -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 "" } diff --git a/gcc/testsuite/g++.dg/concepts/dr1430.C b/gcc/testsuite/g++.dg/concepts/dr1430.C index c22a782..ae58496 100644 --- a/gcc/testsuite/g++.dg/concepts/dr1430.C +++ b/gcc/testsuite/g++.dg/concepts/dr1430.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/equiv.C b/gcc/testsuite/g++.dg/concepts/equiv.C index a5d0c18..7b8a33c 100644 --- a/gcc/testsuite/g++.dg/concepts/equiv.C +++ b/gcc/testsuite/g++.dg/concepts/equiv.C @@ -1,35 +1,36 @@ -// { 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. +// NB: they are not equivalent in C++20. 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>() { } diff --git a/gcc/testsuite/g++.dg/concepts/equiv2.C b/gcc/testsuite/g++.dg/concepts/equiv2.C index 48a2664..0121fb8 100644 --- a/gcc/testsuite/g++.dg/concepts/equiv2.C +++ b/gcc/testsuite/g++.dg/concepts/equiv2.C @@ -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" } +} diff --git a/gcc/testsuite/g++.dg/concepts/expression.C b/gcc/testsuite/g++.dg/concepts/expression.C index 3da0c96..90ee7ce 100644 --- a/gcc/testsuite/g++.dg/concepts/expression.C +++ b/gcc/testsuite/g++.dg/concepts/expression.C @@ -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); diff --git a/gcc/testsuite/g++.dg/concepts/expression2.C b/gcc/testsuite/g++.dg/concepts/expression2.C index 2f7aafc..c0eb4e5 100644 --- a/gcc/testsuite/g++.dg/concepts/expression2.C +++ b/gcc/testsuite/g++.dg/concepts/expression2.C @@ -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 "" } } diff --git a/gcc/testsuite/g++.dg/concepts/expression3.C b/gcc/testsuite/g++.dg/concepts/expression3.C index a2d340d..412e7e9 100644 --- a/gcc/testsuite/g++.dg/concepts/expression3.C +++ b/gcc/testsuite/g++.dg/concepts/expression3.C @@ -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" } } diff --git a/gcc/testsuite/g++.dg/concepts/fn-concept1.C b/gcc/testsuite/g++.dg/concepts/fn-concept1.C deleted file mode 100644 index 4908d11..0000000 --- a/gcc/testsuite/g++.dg/concepts/fn-concept1.C +++ /dev/null @@ -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&); diff --git a/gcc/testsuite/g++.dg/concepts/fn-concept2.C b/gcc/testsuite/g++.dg/concepts/fn-concept2.C index 2876505..799e85d 100644 --- a/gcc/testsuite/g++.dg/concepts/fn-concept2.C +++ b/gcc/testsuite/g++.dg/concepts/fn-concept2.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/fn-concept3.C b/gcc/testsuite/g++.dg/concepts/fn-concept3.C index 88ed5a8..f8637c2 100644 --- a/gcc/testsuite/g++.dg/concepts/fn-concept3.C +++ b/gcc/testsuite/g++.dg/concepts/fn-concept3.C @@ -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>), "concept should be treated as if noexcept(true) specified"); diff --git a/gcc/testsuite/g++.dg/concepts/fn1.C b/gcc/testsuite/g++.dg/concepts/fn1.C index e22cbf7..16c3593 100644 --- a/gcc/testsuite/g++.dg/concepts/fn1.C +++ b/gcc/testsuite/g++.dg/concepts/fn1.C @@ -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, diff --git a/gcc/testsuite/g++.dg/concepts/fn10.C b/gcc/testsuite/g++.dg/concepts/fn10.C index 83099de..e19ac35 100644 --- a/gcc/testsuite/g++.dg/concepts/fn10.C +++ b/gcc/testsuite/g++.dg/concepts/fn10.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/concepts/fn2.C b/gcc/testsuite/g++.dg/concepts/fn2.C index e0ac36f..fbf970e 100644 --- a/gcc/testsuite/g++.dg/concepts/fn2.C +++ b/gcc/testsuite/g++.dg/concepts/fn2.C @@ -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. diff --git a/gcc/testsuite/g++.dg/concepts/fn3.C b/gcc/testsuite/g++.dg/concepts/fn3.C index 3e076f6..546fa7e 100644 --- a/gcc/testsuite/g++.dg/concepts/fn3.C +++ b/gcc/testsuite/g++.dg/concepts/fn3.C @@ -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; diff --git a/gcc/testsuite/g++.dg/concepts/fn4.C b/gcc/testsuite/g++.dg/concepts/fn4.C index 6418677..59fd444 100644 --- a/gcc/testsuite/g++.dg/concepts/fn4.C +++ b/gcc/testsuite/g++.dg/concepts/fn4.C @@ -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; diff --git a/gcc/testsuite/g++.dg/concepts/fn5.C b/gcc/testsuite/g++.dg/concepts/fn5.C index 3decf4e..8b3f089 100644 --- a/gcc/testsuite/g++.dg/concepts/fn5.C +++ b/gcc/testsuite/g++.dg/concepts/fn5.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" } // 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" } diff --git a/gcc/testsuite/g++.dg/concepts/fn6.C b/gcc/testsuite/g++.dg/concepts/fn6.C index 57c4cfb..e948d03 100644 --- a/gcc/testsuite/g++.dg/concepts/fn6.C +++ b/gcc/testsuite/g++.dg/concepts/fn6.C @@ -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() { } diff --git a/gcc/testsuite/g++.dg/concepts/fn7.C b/gcc/testsuite/g++.dg/concepts/fn7.C index 1994fec..ac893ec 100644 --- a/gcc/testsuite/g++.dg/concepts/fn7.C +++ b/gcc/testsuite/g++.dg/concepts/fn7.C @@ -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() { } diff --git a/gcc/testsuite/g++.dg/concepts/fn8.C b/gcc/testsuite/g++.dg/concepts/fn8.C index 594270f..16c64a3 100644 --- a/gcc/testsuite/g++.dg/concepts/fn8.C +++ b/gcc/testsuite/g++.dg/concepts/fn8.C @@ -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) { } diff --git a/gcc/testsuite/g++.dg/concepts/fn9.C b/gcc/testsuite/g++.dg/concepts/fn9.C index 51edd2f..63c3b5a 100644 --- a/gcc/testsuite/g++.dg/concepts/fn9.C +++ b/gcc/testsuite/g++.dg/concepts/fn9.C @@ -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; } diff --git a/gcc/testsuite/g++.dg/concepts/generic-fn-err.C b/gcc/testsuite/g++.dg/concepts/generic-fn-err.C index e4909eb..698aad6 100644 --- a/gcc/testsuite/g++.dg/concepts/generic-fn-err.C +++ b/gcc/testsuite/g++.dg/concepts/generic-fn-err.C @@ -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) { } diff --git a/gcc/testsuite/g++.dg/concepts/generic-fn.C b/gcc/testsuite/g++.dg/concepts/generic-fn.C index 983b370..9af1794 100644 --- a/gcc/testsuite/g++.dg/concepts/generic-fn.C +++ b/gcc/testsuite/g++.dg/concepts/generic-fn.C @@ -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> diff --git a/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C b/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C index 98c260c..e060da4 100644 --- a/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C +++ b/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C @@ -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 { }; diff --git a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C index 76308ff..58700b0 100644 --- a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C +++ b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/concepts/intro1.C b/gcc/testsuite/g++.dg/concepts/intro1.C index 0dd9b64..da4f904 100644 --- a/gcc/testsuite/g++.dg/concepts/intro1.C +++ b/gcc/testsuite/g++.dg/concepts/intro1.C @@ -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> - { - } diff --git a/gcc/testsuite/g++.dg/concepts/intro2.C b/gcc/testsuite/g++.dg/concepts/intro2.C deleted file mode 100644 index 5c6906c..0000000 --- a/gcc/testsuite/g++.dg/concepts/intro2.C +++ /dev/null @@ -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); } diff --git a/gcc/testsuite/g++.dg/concepts/intro3.C b/gcc/testsuite/g++.dg/concepts/intro3.C deleted file mode 100644 index c92338e..0000000 --- a/gcc/testsuite/g++.dg/concepts/intro3.C +++ /dev/null @@ -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; -} diff --git a/gcc/testsuite/g++.dg/concepts/intro4.C b/gcc/testsuite/g++.dg/concepts/intro4.C deleted file mode 100644 index 5ddd162..0000000 --- a/gcc/testsuite/g++.dg/concepts/intro4.C +++ /dev/null @@ -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; -} diff --git a/gcc/testsuite/g++.dg/concepts/intro5.C b/gcc/testsuite/g++.dg/concepts/intro5.C deleted file mode 100644 index cb1c5da..0000000 --- a/gcc/testsuite/g++.dg/concepts/intro5.C +++ /dev/null @@ -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" } - diff --git a/gcc/testsuite/g++.dg/concepts/intro6.C b/gcc/testsuite/g++.dg/concepts/intro6.C deleted file mode 100644 index b718d13..0000000 --- a/gcc/testsuite/g++.dg/concepts/intro6.C +++ /dev/null @@ -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>(); } diff --git a/gcc/testsuite/g++.dg/concepts/intro7.C b/gcc/testsuite/g++.dg/concepts/intro7.C deleted file mode 100644 index 0c452a7..0000000 --- a/gcc/testsuite/g++.dg/concepts/intro7.C +++ /dev/null @@ -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>; -}; diff --git a/gcc/testsuite/g++.dg/concepts/locations1.C b/gcc/testsuite/g++.dg/concepts/locations1.C index ea22743..9553dd1d7 100644 --- a/gcc/testsuite/g++.dg/concepts/locations1.C +++ b/gcc/testsuite/g++.dg/concepts/locations1.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C b/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C index 09c9d4f..712f26d 100644 --- a/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C +++ b/gcc/testsuite/g++.dg/concepts/partial-concept-id1.C @@ -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 { }; diff --git a/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C b/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C index 089f40f..36b8cab 100644 --- a/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C +++ b/gcc/testsuite/g++.dg/concepts/partial-concept-id2.C @@ -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 diff --git a/gcc/testsuite/g++.dg/concepts/partial-spec5.C b/gcc/testsuite/g++.dg/concepts/partial-spec5.C index 954c072..c772d1b 100644 --- a/gcc/testsuite/g++.dg/concepts/partial-spec5.C +++ b/gcc/testsuite/g++.dg/concepts/partial-spec5.C @@ -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 {}; diff --git a/gcc/testsuite/g++.dg/concepts/placeholder2.C b/gcc/testsuite/g++.dg/concepts/placeholder2.C index f1c3b9c..e5ff812 100644 --- a/gcc/testsuite/g++.dg/concepts/placeholder2.C +++ b/gcc/testsuite/g++.dg/concepts/placeholder2.C @@ -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 diff --git a/gcc/testsuite/g++.dg/concepts/placeholder3.C b/gcc/testsuite/g++.dg/concepts/placeholder3.C index 6b79ef6..d9d0f95 100644 --- a/gcc/testsuite/g++.dg/concepts/placeholder3.C +++ b/gcc/testsuite/g++.dg/concepts/placeholder3.C @@ -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" } }; diff --git a/gcc/testsuite/g++.dg/concepts/placeholder4.C b/gcc/testsuite/g++.dg/concepts/placeholder4.C index 1645161..5bd7022 100644 --- a/gcc/testsuite/g++.dg/concepts/placeholder4.C +++ b/gcc/testsuite/g++.dg/concepts/placeholder4.C @@ -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" } }; diff --git a/gcc/testsuite/g++.dg/concepts/placeholder5.C b/gcc/testsuite/g++.dg/concepts/placeholder5.C index 21a6b31..b01336a 100644 --- a/gcc/testsuite/g++.dg/concepts/placeholder5.C +++ b/gcc/testsuite/g++.dg/concepts/placeholder5.C @@ -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" } }; diff --git a/gcc/testsuite/g++.dg/concepts/placeholder6.C b/gcc/testsuite/g++.dg/concepts/placeholder6.C index c7f62d1..767cca6 100644 --- a/gcc/testsuite/g++.dg/concepts/placeholder6.C +++ b/gcc/testsuite/g++.dg/concepts/placeholder6.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/pr65634.C b/gcc/testsuite/g++.dg/concepts/pr65634.C index 650d10e..e65df6b 100644 --- a/gcc/testsuite/g++.dg/concepts/pr65634.C +++ b/gcc/testsuite/g++.dg/concepts/pr65634.C @@ -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>, ""); diff --git a/gcc/testsuite/g++.dg/concepts/pr65636.C b/gcc/testsuite/g++.dg/concepts/pr65636.C index 69091dc..76a4214 100644 --- a/gcc/testsuite/g++.dg/concepts/pr65636.C +++ b/gcc/testsuite/g++.dg/concepts/pr65636.C @@ -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>, ""); diff --git a/gcc/testsuite/g++.dg/concepts/pr65681.C b/gcc/testsuite/g++.dg/concepts/pr65681.C index cf34911..9a4615d 100644 --- a/gcc/testsuite/g++.dg/concepts/pr65681.C +++ b/gcc/testsuite/g++.dg/concepts/pr65681.C @@ -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(); }; diff --git a/gcc/testsuite/g++.dg/concepts/pr65848.C b/gcc/testsuite/g++.dg/concepts/pr65848.C index 76e6f6f..600b48b 100644 --- a/gcc/testsuite/g++.dg/concepts/pr65848.C +++ b/gcc/testsuite/g++.dg/concepts/pr65848.C @@ -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>, ""); diff --git a/gcc/testsuite/g++.dg/concepts/pr67249.C b/gcc/testsuite/g++.dg/concepts/pr67249.C index 75f0ea0..e0f8d5a 100644 --- a/gcc/testsuite/g++.dg/concepts/pr67249.C +++ b/gcc/testsuite/g++.dg/concepts/pr67249.C @@ -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>); diff --git a/gcc/testsuite/g++.dg/concepts/pr67595.C b/gcc/testsuite/g++.dg/concepts/pr67595.C index 33122d2..7412966 100644 --- a/gcc/testsuite/g++.dg/concepts/pr67595.C +++ b/gcc/testsuite/g++.dg/concepts/pr67595.C @@ -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 "" } diff --git a/gcc/testsuite/g++.dg/concepts/pr68434.C b/gcc/testsuite/g++.dg/concepts/pr68434.C index ff6a898..e03d2a4 100644 --- a/gcc/testsuite/g++.dg/concepts/pr68434.C +++ b/gcc/testsuite/g++.dg/concepts/pr68434.C @@ -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); diff --git a/gcc/testsuite/g++.dg/concepts/pr71127.C b/gcc/testsuite/g++.dg/concepts/pr71127.C index e76aec1..9c9a77a 100644 --- a/gcc/testsuite/g++.dg/concepts/pr71127.C +++ b/gcc/testsuite/g++.dg/concepts/pr71127.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/pr71128.C b/gcc/testsuite/g++.dg/concepts/pr71128.C index 351a646..63b3d1d 100644 --- a/gcc/testsuite/g++.dg/concepts/pr71128.C +++ b/gcc/testsuite/g++.dg/concepts/pr71128.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/pr71131.C b/gcc/testsuite/g++.dg/concepts/pr71131.C index 8da43af..8123726 100644 --- a/gcc/testsuite/g++.dg/concepts/pr71131.C +++ b/gcc/testsuite/g++.dg/concepts/pr71131.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/pr71385.C b/gcc/testsuite/g++.dg/concepts/pr71385.C index 66ca52b..fcafd2d 100644 --- a/gcc/testsuite/g++.dg/concepts/pr71385.C +++ b/gcc/testsuite/g++.dg/concepts/pr71385.C @@ -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; } diff --git a/gcc/testsuite/g++.dg/concepts/pr85065.C b/gcc/testsuite/g++.dg/concepts/pr85065.C index 72f2aca..b959611 100644 --- a/gcc/testsuite/g++.dg/concepts/pr85065.C +++ b/gcc/testsuite/g++.dg/concepts/pr85065.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/pr92804-2.C b/gcc/testsuite/g++.dg/concepts/pr92804-2.C index 32a1554..60ff421 100644 --- a/gcc/testsuite/g++.dg/concepts/pr92804-2.C +++ b/gcc/testsuite/g++.dg/concepts/pr92804-2.C @@ -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) diff --git a/gcc/testsuite/g++.dg/concepts/template-parm11.C b/gcc/testsuite/g++.dg/concepts/template-parm11.C index b376a49..76af3d6 100644 --- a/gcc/testsuite/g++.dg/concepts/template-parm11.C +++ b/gcc/testsuite/g++.dg/concepts/template-parm11.C @@ -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&...) diff --git a/gcc/testsuite/g++.dg/concepts/template-parm12.C b/gcc/testsuite/g++.dg/concepts/template-parm12.C index 81d0818..4edc55f 100644 --- a/gcc/testsuite/g++.dg/concepts/template-parm12.C +++ b/gcc/testsuite/g++.dg/concepts/template-parm12.C @@ -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" } } diff --git a/gcc/testsuite/g++.dg/concepts/template-parm2.C b/gcc/testsuite/g++.dg/concepts/template-parm2.C index dc6983a..8c74770 100644 --- a/gcc/testsuite/g++.dg/concepts/template-parm2.C +++ b/gcc/testsuite/g++.dg/concepts/template-parm2.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/template-parm3.C b/gcc/testsuite/g++.dg/concepts/template-parm3.C index 2e6bd2c..285578b 100644 --- a/gcc/testsuite/g++.dg/concepts/template-parm3.C +++ b/gcc/testsuite/g++.dg/concepts/template-parm3.C @@ -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 "" } diff --git a/gcc/testsuite/g++.dg/concepts/template-parm4.C b/gcc/testsuite/g++.dg/concepts/template-parm4.C index 8f8ad63..190248a 100644 --- a/gcc/testsuite/g++.dg/concepts/template-parm4.C +++ b/gcc/testsuite/g++.dg/concepts/template-parm4.C @@ -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; diff --git a/gcc/testsuite/g++.dg/concepts/template-template-parm1.C b/gcc/testsuite/g++.dg/concepts/template-template-parm1.C index 019a933..fc43426 100644 --- a/gcc/testsuite/g++.dg/concepts/template-template-parm1.C +++ b/gcc/testsuite/g++.dg/concepts/template-template-parm1.C @@ -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> diff --git a/gcc/testsuite/g++.dg/concepts/var-concept1.C b/gcc/testsuite/g++.dg/concepts/var-concept1.C index 3a3b340..442e5e2 100644 --- a/gcc/testsuite/g++.dg/concepts/var-concept1.C +++ b/gcc/testsuite/g++.dg/concepts/var-concept1.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 {}; diff --git a/gcc/testsuite/g++.dg/concepts/var-concept2.C b/gcc/testsuite/g++.dg/concepts/var-concept2.C index 0ef2322..ab17838 100644 --- a/gcc/testsuite/g++.dg/concepts/var-concept2.C +++ b/gcc/testsuite/g++.dg/concepts/var-concept2.C @@ -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 () { diff --git a/gcc/testsuite/g++.dg/concepts/var-concept3.C b/gcc/testsuite/g++.dg/concepts/var-concept3.C index b4483eb..d19a913 100644 --- a/gcc/testsuite/g++.dg/concepts/var-concept3.C +++ b/gcc/testsuite/g++.dg/concepts/var-concept3.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/var-concept4.C b/gcc/testsuite/g++.dg/concepts/var-concept4.C index 7ae9f36..3a352aa 100644 --- a/gcc/testsuite/g++.dg/concepts/var-concept4.C +++ b/gcc/testsuite/g++.dg/concepts/var-concept4.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/var-concept5.C b/gcc/testsuite/g++.dg/concepts/var-concept5.C index cc7f4af..b5dd600 100644 --- a/gcc/testsuite/g++.dg/concepts/var-concept5.C +++ b/gcc/testsuite/g++.dg/concepts/var-concept5.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/var-concept6.C b/gcc/testsuite/g++.dg/concepts/var-concept6.C index d2270df..04298f4 100644 --- a/gcc/testsuite/g++.dg/concepts/var-concept6.C +++ b/gcc/testsuite/g++.dg/concepts/var-concept6.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/var-concept7.C b/gcc/testsuite/g++.dg/concepts/var-concept7.C index 026fe9f..441fbac 100644 --- a/gcc/testsuite/g++.dg/concepts/var-concept7.C +++ b/gcc/testsuite/g++.dg/concepts/var-concept7.C @@ -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 "" } diff --git a/gcc/testsuite/g++.dg/concepts/var-templ1.C b/gcc/testsuite/g++.dg/concepts/var-templ1.C index 4ac578f..b69d7d8d 100644 --- a/gcc/testsuite/g++.dg/concepts/var-templ1.C +++ b/gcc/testsuite/g++.dg/concepts/var-templ1.C @@ -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> diff --git a/gcc/testsuite/g++.dg/concepts/var-templ2.C b/gcc/testsuite/g++.dg/concepts/var-templ2.C index 2eb419a..c564c07 100644 --- a/gcc/testsuite/g++.dg/concepts/var-templ2.C +++ b/gcc/testsuite/g++.dg/concepts/var-templ2.C @@ -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>()), ""); diff --git a/gcc/testsuite/g++.dg/concepts/var-templ3.C b/gcc/testsuite/g++.dg/concepts/var-templ3.C index 662511e..0b3899a 100644 --- a/gcc/testsuite/g++.dg/concepts/var-templ3.C +++ b/gcc/testsuite/g++.dg/concepts/var-templ3.C @@ -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 {}; diff --git a/gcc/testsuite/g++.dg/concepts/variadic1.C b/gcc/testsuite/g++.dg/concepts/variadic1.C index c590f28..aad6db0 100644 --- a/gcc/testsuite/g++.dg/concepts/variadic1.C +++ b/gcc/testsuite/g++.dg/concepts/variadic1.C @@ -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 diff --git a/gcc/testsuite/g++.dg/concepts/variadic2.C b/gcc/testsuite/g++.dg/concepts/variadic2.C index 1776b95..93380ae 100644 --- a/gcc/testsuite/g++.dg/concepts/variadic2.C +++ b/gcc/testsuite/g++.dg/concepts/variadic2.C @@ -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 diff --git a/gcc/testsuite/g++.dg/concepts/variadic3.C b/gcc/testsuite/g++.dg/concepts/variadic3.C index 07c2401..e8a20bb 100644 --- a/gcc/testsuite/g++.dg/concepts/variadic3.C +++ b/gcc/testsuite/g++.dg/concepts/variadic3.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/concepts/variadic4.C b/gcc/testsuite/g++.dg/concepts/variadic4.C index 1dfa2e6..1c0612b 100644 --- a/gcc/testsuite/g++.dg/concepts/variadic4.C +++ b/gcc/testsuite/g++.dg/concepts/variadic4.C @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C index bec97e9..79e9472 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C @@ -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(); } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C index cd3acf7..7ad7919 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C @@ -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; } }; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67148.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67148.C index 97f80cf..360817b 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67148.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67148.C @@ -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; } }} }} diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C index d59d4f9..1b63c46 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-1.C @@ -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() {} diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-2.C index f8d99ff..1b3538d 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-2.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-2.C @@ -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 (); } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-3.C index 937098d..4754193 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-3.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-3.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-4.C index e37ad28..1f39b93 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-4.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-4.C @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-5.C index 92f4298..f649ceb 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-5.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67225-5.C @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67319.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67319.C index 5399780..338251c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67319.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67319.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67427.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67427.C index fad43be..c5d175d 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67427.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67427.C @@ -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> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67654.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67654.C index 5087344..352407d 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67654.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67654.C @@ -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() { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67658.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67658.C index 530cb33..cd82a84 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67658.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67658.C @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67684.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67684.C index 3924922..b0e9190 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67684.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67684.C @@ -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; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67697.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67697.C index 2708337..625d9ef 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67697.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67697.C @@ -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; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67719.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67719.C index c3c5c23..cd03f6e 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67719.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67719.C @@ -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 {}; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67774.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67774.C index 5ee5c2d..58c5002 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67774.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67774.C @@ -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() { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C index 64cd9d2..9f5051f 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C @@ -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; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67860.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67860.C index 693237f..8807a8c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67860.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67860.C @@ -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> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67862.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67862.C index b42ce8b..e0b869c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67862.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67862.C @@ -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>; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67969.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67969.C index b809553..83dee70 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67969.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67969.C @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-2.C index 2dd46da..0085191 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-2.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68093-2.C @@ -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() { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68372.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68372.C index 9fc90ff..95e9c32 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68372.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68372.C @@ -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...) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68812.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68812.C index 324b3ad..46bc759 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr68812.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr68812.C @@ -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 diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr69235.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr69235.C index 1df563b..2b5d012 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr69235.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr69235.C @@ -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; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752-2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752-2.C index 7d7c716..af2fb8a 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752-2.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752-2.C @@ -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() { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752.C index 447b149..6cf4f21 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr78752.C @@ -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> diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr79759.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr79759.C index 5fdd64e..54f8855 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr79759.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr79759.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr80746.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr80746.C index 1a0008e..f083ba5 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr80746.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr80746.C @@ -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 {}; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr80773.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr80773.C index 92e89da..a39977e 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr80773.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr80773.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr82507.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr82507.C index 81a671c..81b4fdae 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr82507.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr82507.C @@ -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 diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr82740.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr82740.C index 01a42a4..81b258d 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr82740.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr82740.C @@ -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 diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C index 635a168..fb0042c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C deleted file mode 100644 index d351b45..0000000 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C +++ /dev/null @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85808.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85808.C index f32ca63..0c836a9 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr85808.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr85808.C @@ -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>; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr86269.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr86269.C index 6fb430d..0f6c764 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr86269.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr86269.C @@ -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) diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr87441.C b/gcc/testsuite/g++.dg/cpp2a/concepts-pr87441.C index 28be9e9..2d16d05 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr87441.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr87441.C @@ -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); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C index 976efe6..524eadb 100644 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C @@ -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 { }; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C deleted file mode 100644 index a116cac..0000000 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C +++ /dev/null @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C deleted file mode 100644 index 5942ff1..0000000 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C +++ /dev/null @@ -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&); diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C deleted file mode 100644 index 6f7ed1f..0000000 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C +++ /dev/null @@ -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" } - diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C deleted file mode 100644 index cc49ff4..0000000 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C +++ /dev/null @@ -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 } -} diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts5.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts5.C deleted file mode 100644 index 0624488..0000000 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts5.C +++ /dev/null @@ -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" } -}; diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-ts6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-ts6.C deleted file mode 100644 index 8aede57..0000000 --- a/gcc/testsuite/g++.dg/cpp2a/concepts-ts6.C +++ /dev/null @@ -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" } -} diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C index eb8a6ad..7c23d24 100644 --- a/gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C +++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C @@ -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" diff --git a/libstdc++-v3/testsuite/std/ranges/access/101782.cc b/libstdc++-v3/testsuite/std/ranges/access/101782.cc index 25fea79..1ffeccb 100644 --- a/libstdc++-v3/testsuite/std/ranges/access/101782.cc +++ b/libstdc++-v3/testsuite/std/ranges/access/101782.cc @@ -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 |