From f0fb6b6acd805cfd3197eaf78d5404fa45759727 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 31 May 2024 08:54:00 -0400 Subject: [PATCH] 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 concept C = true; C{T} void foo (T); // write template 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. --- gcc/c-family/c-cppbuiltin.cc | 7 +- gcc/c-family/c-opts.cc | 13 +- gcc/c-family/c.opt | 4 +- gcc/c-family/c.opt.urls | 3 - gcc/cp/constraint.cc | 282 ------------------ gcc/cp/cp-tree.h | 2 - gcc/cp/decl.cc | 18 +- gcc/cp/parser.cc | 260 +++------------- gcc/cp/pt.cc | 175 +---------- gcc/doc/invoke.texi | 4 +- gcc/testsuite/g++.dg/concepts/auto1.C | 28 -- gcc/testsuite/g++.dg/concepts/auto3.C | 12 +- gcc/testsuite/g++.dg/concepts/auto4.C | 12 - gcc/testsuite/g++.dg/concepts/auto5.C | 8 +- gcc/testsuite/g++.dg/concepts/auto6.C | 14 - gcc/testsuite/g++.dg/concepts/auto7.C | 4 +- gcc/testsuite/g++.dg/concepts/auto8a.C | 2 +- .../g++.dg/concepts/class-deduction1.C | 6 +- gcc/testsuite/g++.dg/concepts/class5.C | 8 +- gcc/testsuite/g++.dg/concepts/class6.C | 8 +- gcc/testsuite/g++.dg/concepts/debug1.C | 10 +- gcc/testsuite/g++.dg/concepts/decl-diagnose.C | 10 +- .../g++.dg/concepts/deduction-constraint1.C | 9 +- gcc/testsuite/g++.dg/concepts/diagnostic1.C | 20 +- gcc/testsuite/g++.dg/concepts/dr1430.C | 17 +- gcc/testsuite/g++.dg/concepts/equiv.C | 45 +-- gcc/testsuite/g++.dg/concepts/equiv2.C | 27 +- gcc/testsuite/g++.dg/concepts/expression.C | 10 +- gcc/testsuite/g++.dg/concepts/expression2.C | 24 +- gcc/testsuite/g++.dg/concepts/expression3.C | 14 +- gcc/testsuite/g++.dg/concepts/fn-concept1.C | 10 - gcc/testsuite/g++.dg/concepts/fn-concept2.C | 8 +- gcc/testsuite/g++.dg/concepts/fn-concept3.C | 8 +- gcc/testsuite/g++.dg/concepts/fn1.C | 8 +- gcc/testsuite/g++.dg/concepts/fn10.C | 22 +- gcc/testsuite/g++.dg/concepts/fn2.C | 8 +- gcc/testsuite/g++.dg/concepts/fn3.C | 8 +- gcc/testsuite/g++.dg/concepts/fn4.C | 8 +- gcc/testsuite/g++.dg/concepts/fn5.C | 12 +- gcc/testsuite/g++.dg/concepts/fn6.C | 12 +- gcc/testsuite/g++.dg/concepts/fn7.C | 4 +- gcc/testsuite/g++.dg/concepts/fn8.C | 6 +- gcc/testsuite/g++.dg/concepts/fn9.C | 8 +- .../g++.dg/concepts/generic-fn-err.C | 18 +- gcc/testsuite/g++.dg/concepts/generic-fn.C | 52 ++-- gcc/testsuite/g++.dg/concepts/inherit-ctor1.C | 6 +- gcc/testsuite/g++.dg/concepts/inherit-ctor3.C | 6 +- gcc/testsuite/g++.dg/concepts/intro1.C | 38 +-- gcc/testsuite/g++.dg/concepts/intro2.C | 27 -- gcc/testsuite/g++.dg/concepts/intro3.C | 18 -- gcc/testsuite/g++.dg/concepts/intro4.C | 33 -- gcc/testsuite/g++.dg/concepts/intro5.C | 11 - gcc/testsuite/g++.dg/concepts/intro6.C | 13 - gcc/testsuite/g++.dg/concepts/intro7.C | 14 - gcc/testsuite/g++.dg/concepts/locations1.C | 5 +- .../g++.dg/concepts/partial-concept-id1.C | 14 +- .../g++.dg/concepts/partial-concept-id2.C | 6 +- gcc/testsuite/g++.dg/concepts/partial-spec5.C | 6 +- gcc/testsuite/g++.dg/concepts/placeholder2.C | 12 +- gcc/testsuite/g++.dg/concepts/placeholder3.C | 8 +- gcc/testsuite/g++.dg/concepts/placeholder4.C | 8 +- gcc/testsuite/g++.dg/concepts/placeholder5.C | 8 +- gcc/testsuite/g++.dg/concepts/placeholder6.C | 6 +- gcc/testsuite/g++.dg/concepts/pr65634.C | 18 +- gcc/testsuite/g++.dg/concepts/pr65636.C | 11 +- gcc/testsuite/g++.dg/concepts/pr65681.C | 18 +- gcc/testsuite/g++.dg/concepts/pr65848.C | 86 +++--- gcc/testsuite/g++.dg/concepts/pr67249.C | 9 +- gcc/testsuite/g++.dg/concepts/pr67595.C | 15 +- gcc/testsuite/g++.dg/concepts/pr68434.C | 22 +- gcc/testsuite/g++.dg/concepts/pr71127.C | 6 +- gcc/testsuite/g++.dg/concepts/pr71128.C | 8 +- gcc/testsuite/g++.dg/concepts/pr71131.C | 6 +- gcc/testsuite/g++.dg/concepts/pr71385.C | 13 +- gcc/testsuite/g++.dg/concepts/pr85065.C | 6 +- gcc/testsuite/g++.dg/concepts/pr92804-2.C | 4 +- .../g++.dg/concepts/template-parm11.C | 10 +- .../g++.dg/concepts/template-parm12.C | 8 +- .../g++.dg/concepts/template-parm2.C | 18 +- .../g++.dg/concepts/template-parm3.C | 24 +- .../g++.dg/concepts/template-parm4.C | 18 +- .../g++.dg/concepts/template-template-parm1.C | 10 +- gcc/testsuite/g++.dg/concepts/var-concept1.C | 12 +- gcc/testsuite/g++.dg/concepts/var-concept2.C | 8 +- gcc/testsuite/g++.dg/concepts/var-concept3.C | 12 +- gcc/testsuite/g++.dg/concepts/var-concept4.C | 16 +- gcc/testsuite/g++.dg/concepts/var-concept5.C | 8 +- gcc/testsuite/g++.dg/concepts/var-concept6.C | 6 +- gcc/testsuite/g++.dg/concepts/var-concept7.C | 14 +- gcc/testsuite/g++.dg/concepts/var-templ1.C | 2 +- gcc/testsuite/g++.dg/concepts/var-templ2.C | 13 +- gcc/testsuite/g++.dg/concepts/var-templ3.C | 9 +- gcc/testsuite/g++.dg/concepts/variadic1.C | 9 +- gcc/testsuite/g++.dg/concepts/variadic2.C | 10 +- gcc/testsuite/g++.dg/concepts/variadic3.C | 6 +- gcc/testsuite/g++.dg/concepts/variadic4.C | 6 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr65575.C | 20 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr66091.C | 20 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67148.C | 38 +-- .../g++.dg/cpp2a/concepts-pr67225-1.C | 13 +- .../g++.dg/cpp2a/concepts-pr67225-2.C | 10 +- .../g++.dg/cpp2a/concepts-pr67225-3.C | 4 +- .../g++.dg/cpp2a/concepts-pr67225-4.C | 6 +- .../g++.dg/cpp2a/concepts-pr67225-5.C | 6 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67319.C | 8 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67427.C | 9 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67654.C | 8 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67658.C | 8 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67684.C | 18 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67697.C | 9 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67719.C | 7 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67774.C | 9 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67825.C | 9 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67860.C | 12 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr67862.C | 56 ++-- gcc/testsuite/g++.dg/cpp2a/concepts-pr67969.C | 16 +- .../g++.dg/cpp2a/concepts-pr68093-2.C | 8 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr68372.C | 11 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr68812.C | 4 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr69235.C | 22 +- .../g++.dg/cpp2a/concepts-pr78752-2.C | 10 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr78752.C | 4 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr79759.C | 6 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr80746.C | 4 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr80773.C | 9 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr82507.C | 6 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr82740.C | 4 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr84980.C | 6 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C | 7 - gcc/testsuite/g++.dg/cpp2a/concepts-pr85808.C | 4 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr86269.C | 4 +- gcc/testsuite/g++.dg/cpp2a/concepts-pr87441.C | 8 +- .../g++.dg/cpp2a/concepts-requires5.C | 10 +- gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C | 49 --- gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C | 260 ---------------- gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C | 251 ---------------- gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C | 36 --- gcc/testsuite/g++.dg/cpp2a/concepts-ts5.C | 10 - gcc/testsuite/g++.dg/cpp2a/concepts-ts6.C | 74 ----- gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C | 2 +- .../testsuite/std/ranges/access/101782.cc | 2 +- 141 files changed, 712 insertions(+), 2313 deletions(-) delete mode 100644 gcc/testsuite/g++.dg/concepts/auto1.C delete mode 100644 gcc/testsuite/g++.dg/concepts/auto4.C delete mode 100644 gcc/testsuite/g++.dg/concepts/auto6.C delete mode 100644 gcc/testsuite/g++.dg/concepts/fn-concept1.C delete mode 100644 gcc/testsuite/g++.dg/concepts/intro2.C delete mode 100644 gcc/testsuite/g++.dg/concepts/intro3.C delete mode 100644 gcc/testsuite/g++.dg/concepts/intro4.C delete mode 100644 gcc/testsuite/g++.dg/concepts/intro5.C delete mode 100644 gcc/testsuite/g++.dg/concepts/intro6.C delete mode 100644 gcc/testsuite/g++.dg/concepts/intro7.C delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr85265.C delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ts1.C delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ts2.C delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ts3.C delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ts4.C delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ts5.C delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-ts6.C diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc index dfd8f6f0c485..a80372c89914 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 b7789b707e63..7d210334b016 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 864ef4e3b3d1..5c1006ff321f 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 31d9ffef578f..1b60ae4847b1 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 ebf4255e546e..5472cc51b8ad 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 struct s; - - If C is variadic (and because Ts is a pack), we associate the - constraint C. In all other cases, we associate - the constraint (C && ...). - - 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 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 4bb3e9c4989b..f270b0b1077d 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 29616100cfe8..d4c65a199329 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 %"); 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 31ae9c2fb54d..6bf3f52a0599 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 % keyword is not " - "allowed in a C++20 concept definition"); - else - error_at (token->location, "C++20 concept definition syntax " - "is % = %>"); - } + { + cp_token *next = cp_lexer_peek_token (parser->lexer); + if (next->keyword == RID_BOOL) + permerror (next->location, "the % keyword is not " + "allowed in a C++20 concept definition"); + else + error_at (token->location, "C++20 concept definition syntax " + "is % = %>"); + } /* 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 *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 % in template argument " - "only available with %<-fconcepts-ts%>"); + else if (parser->in_template_argument_list_p) + error_at (token->location, + "use of % in template argument"); else if (!flag_concepts) pedwarn (token->location, 0, "use of % 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 % 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 d1316483e245..e38e02488be1 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 *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; - 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; 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; - 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; - 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; - 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 &hash = *(hash_table*)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 visited; - hash_table 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 4d671c4f6d89..4850c7379bfa 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 abf7886c9f64..000000000000 --- 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 A { }; - -A a; -A a2; -A a22; - -A b = a; -A b1 = a2; - -template concept bool C = __is_same_as (T, int); - -A b2 = a; -A b3 = a2; // { dg-error "" } -A b32 = a22; // { dg-error "" } - -template concept bool C2() { return __is_enum (T); } - -enum E1 { }; -enum E2 { }; - -A a3; -A b4 = a3; - -A a4; -A b5 = a4; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/concepts/auto3.C b/gcc/testsuite/g++.dg/concepts/auto3.C index 868a56cf3159..5c91cc08f2e3 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 tuple {}; tuple t; -tuple y = t; +tuple y = t; // { dg-error "invalid|cannot convert" } tuple t2; -tuple x = t2; -tuple x2 = t; +tuple x = t2; // { dg-error "invalid|cannot convert" } +tuple x2 = t; // { dg-error "invalid|cannot convert" } -tuple y2 = t2; // { dg-error "" } +tuple 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 6c984550229b..000000000000 --- 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 struct A {}; - -template A 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 f1d653efd87c..5538f2ebc019 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 struct A { }; A a; -A b1 = a; -A b2 = a; +A b1 = a; // { dg-error "invalid|cannot convert" } +A 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 1f6d72e54ccf..000000000000 --- 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 struct A { }; - -template -void f() { - A a; - A b1 = a; - A b2 = a; -} - -template void f(); diff --git a/gcc/testsuite/g++.dg/concepts/auto7.C b/gcc/testsuite/g++.dg/concepts/auto7.C index 3cbf5dd8dfcd..26c9e9e7bca7 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 struct A { }; -void f(A a) { } +void f(A a) { } // { dg-error "use of .auto. in template argument" } int main() { f(A()); diff --git a/gcc/testsuite/g++.dg/concepts/auto8a.C b/gcc/testsuite/g++.dg/concepts/auto8a.C index fc60dc871c20..f4b0d969157d 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 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 7f427d053b88..5d4b1499047d 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 -concept bool Isint = __is_same_as(T,int); +concept Isint = __is_same_as(T,int); template struct A diff --git a/gcc/testsuite/g++.dg/concepts/class5.C b/gcc/testsuite/g++.dg/concepts/class5.C index 5f8ece965439..02d670ebe9f2 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 - concept bool One() { return sizeof(T) >= 4; } + concept One = sizeof(T) >= 4; template - concept bool Two() { return One() && sizeof(T) >= 8; } + concept Two = One && sizeof(T) >= 8; // Check ordering of partial specializaitons template diff --git a/gcc/testsuite/g++.dg/concepts/class6.C b/gcc/testsuite/g++.dg/concepts/class6.C index a1c5e166e553..77f7203b41fd 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 - concept bool One() { return sizeof(T) >= 4; } + concept One = sizeof(T) >= 4; template - concept bool Two() { return One() && sizeof(T) >= 8; } + concept Two = One && sizeof(T) >= 8; // Check that there is no ecsacpe hatch template struct S4 { }; diff --git a/gcc/testsuite/g++.dg/concepts/debug1.C b/gcc/testsuite/g++.dg/concepts/debug1.C index fb48567249f0..43af4191a48d 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 concept bool C() { return true; } +template concept C = true; -template requires C() class TT> struct A {}; +template requires C class TT> struct A {}; -template requires C() struct B {}; +template requires C struct B {}; A a; diff --git a/gcc/testsuite/g++.dg/concepts/decl-diagnose.C b/gcc/testsuite/g++.dg/concepts/decl-diagnose.C index 96038fd3dfc7..0d10ce1ea9f8 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 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 concept bool X3; // { dg-error "has no initializer" } + // { dg-error "keyword is not allowed" "" { target *-*-* } .-1 } struct S { template 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 d510fe00f2ca..4350f59dc5c6 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 -concept bool A = +concept A = requires (U u) { u; }; template -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 207c36c320e4..2f299b373574 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 -concept bool SameAs = __is_same_as(T, U); +concept SameAs = __is_same_as(T, U); template -concept bool R1 = requires (T& t) { // { dg-message "in requirements" } - { t.begin() } -> T; // { dg-error "no match" } - { t.end() } -> SameAs; // { 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; // { dg-error "deduced expression type" } }; template -concept bool R2 = requires (T& t) { // { dg-message "in requirements" } - { t.end() } -> SameAs; // { dg-message "does not satisfy" } +concept R2 = requires (T& t) { + { t.end() } -> SameAs; // { dg-error "deduced expression type" } }; struct foo { @@ -21,10 +21,10 @@ struct foo { int* end(); }; -R1{T} +template constexpr bool f() { return true; } -R2{T} +template constexpr bool g() { return true; } static_assert(f()); // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/concepts/dr1430.C b/gcc/testsuite/g++.dg/concepts/dr1430.C index c22a7827eba7..ae58496d1eef 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 @@ -20,20 +20,15 @@ requires (sizeof...(Args) > 0) } template - concept bool Same() - { - return decltype(check())::value; - } + concept Same = + decltype(check())::value; template - concept bool Similar = true; + concept Similar = true; template -requires Same() // { dg-error "" "" { xfail *-*-* } } +requires Same() // { 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 requires Similar // { dg-error "pack expansion" } diff --git a/gcc/testsuite/g++.dg/concepts/equiv.C b/gcc/testsuite/g++.dg/concepts/equiv.C index a5d0c1864c09..7b8a33c1aa13 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 - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template - 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 void f2(T x); -void f3(C x); -template void f4(T x) requires D(); -template void f5(T x) requires D(); -template void f6(T x) requires D(); +void f3(C auto x); +template void f4(T x) requires D; +template void f5(T x) requires D; +template void f6(T x) requires D; + +template requires C void f1(T x) { } +template requires C void f2(T x) { } +template void f3(T x) { } +template requires C void f4(T x) requires D { } +template requires C and D void f5(T x) { } +template void f6(T x) requires C and D { } 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 requires C() void f1(T x) { } -template requires C() void f2(T x) { } -template void f3(T x) { } -template requires C() void f4(T x) requires D() { } -template requires C() and D() void f5(T x) { } -template void f6(T x) requires C() and D() { } diff --git a/gcc/testsuite/g++.dg/concepts/equiv2.C b/gcc/testsuite/g++.dg/concepts/equiv2.C index 48a266498f9b..0121fb8039f7 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 // concept bool C() { return true; } template -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 void f2(T1, T2) { } @@ -27,3 +20,9 @@ void f2(T1, T2) { } template requires C && C 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 3da0c962888a..90ee7cecf857 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 #include template - concept bool C1 = __is_class(T); + concept C1 = __is_class(T); template - concept bool C3 = requires (T a) { ++a; }; + concept C3 = requires (T a) { ++a; }; int main() { if (C1) assert(false); diff --git a/gcc/testsuite/g++.dg/concepts/expression2.C b/gcc/testsuite/g++.dg/concepts/expression2.C index 2f7aafc8b6bd..c0eb4e545ffe 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 -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 -concept bool C2() -{ - return requires { typename T::type; }; // { dg-message "in requirements" } -} +concept C2 = + requires { typename T::type; }; // { dg-message "in requirements" } template - requires C1() + requires C1 void f1(T x) { } template - requires C2() + requires C2 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(), ""); // { dg-error "failed" } - static_assert(C2(), ""); // { dg-error "" } + static_assert(C1, ""); // { dg-error "failed" } + static_assert(C2, ""); // { dg-error "" } } diff --git a/gcc/testsuite/g++.dg/concepts/expression3.C b/gcc/testsuite/g++.dg/concepts/expression3.C index a2d340dfaca5..412e7e9e03ee 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 -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(), ""); // { dg-error "failed" } - static_assert(C(), ""); // { dg-error "failed" } + static_assert(C, ""); // { dg-error "failed" } + static_assert(C, ""); // { 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 4908d11d56d8..000000000000 --- 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 - 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 28765054b5ce..799e85de9552 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 concept auto C1() { return 0; } // { dg-error "16:concept .concept auto C1\\(\\). declared with a deduced return type" } template concept int C2() { return 0; } // { dg-error "15:concept .concept int C2\\(\\). with non-.bool. return type .int." } - -template - 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 88ed5a8e8b27..f8637c2f03e5 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 concept bool C3() { return true; } -static_assert(noexcept(C3()), "function concept should be treated as if noexcept(true) specified"); +template concept C3 = true; +static_assert(noexcept(C3), "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 e22cbf70a46b..16c3593613ed 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 - concept bool C() { return __is_class(T); } + concept C = __is_class(T); struct S { } s; template - requires C() + requires C 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 83099de90a14..e19ac35527fd 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 - concept bool Float() - { - return __is_same_as( T, float ); - } + concept Float = __is_same_as( T, float ); template constexpr decltype(auto) project( T t ) @@ -38,12 +35,9 @@ template } template - concept bool Concept() - { - return requires( T t ) { // { dg-message "in requirements" } - requires Float(); + concept Concept = requires( T t ) { // { dg-message "in requirements" } + requires Float; }; - } template constexpr decltype(auto) operator<<( E&& e, F&& f ) {} @@ -59,13 +53,11 @@ template template -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 e0ac36ff3dda..fbf970ed9ee0 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 - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template - requires C() + requires C 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 3e076f62ee88..546fa7eb85f5 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 // Check partial ordering during overload resolution. template - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template - concept bool D() { return C() and __is_empty(T); } + concept D = C 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 64186778f281..59fd44420bce 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 - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template - concept bool D() { return C() and __is_empty(T); } + concept D = C 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 3decf4e38ee3..8b3f08966310 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 - concept bool Type() { return true; } + concept Type = true; template - concept bool Same() { return __is_same_as(T, U); } + concept Same = __is_same_as(T, U); template T> struct S1 { }; template U> struct S2 { }; -void f(Same q) { } -void g(Type a, Same b) { } +void f(Same auto q) { } +void g(Type auto a, Same auto b) { } int main() { S1 s1; // { dg-error "constraint|invalid" } diff --git a/gcc/testsuite/g++.dg/concepts/fn6.C b/gcc/testsuite/g++.dg/concepts/fn6.C index 57c4cfbd016e..e948d03139e4 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 - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template - concept bool D() { return C() and __is_empty(T); } + concept D = C and __is_empty(T); template void f(T x) { } template - requires C() - void f(T x) { } // { dg-error "redefinition" } + requires C + 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 1994feca84ba..ac893ecd318a 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 594270f5178d..16c64a3be3ac 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 - concept bool Class() { return __is_class(T); } + concept Class = __is_class(T); template void f(T) { } diff --git a/gcc/testsuite/g++.dg/concepts/fn9.C b/gcc/testsuite/g++.dg/concepts/fn9.C index 51edd2fc539d..63c3b5a79c6d 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 template - concept bool Class() { return __is_class(T); } + concept Class = __is_class(T); template - concept bool Empty() { return Class() and __is_empty(T); } + concept Empty = Class and __is_empty(T); template int f(T) { return 1; } template 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 e4909eb50bff..698aad6e201e 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 - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template - concept bool Int() { return true; } + concept Int = true; template 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 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 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 983b37092f8f..9af1794b49eb 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 #include template - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template - 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 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 void g1(T t, U u) { called = 1; } @@ -55,27 +55,27 @@ template }; -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::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::value, "not an lvalue reference"); using U = typename std::remove_reference::type; static_assert(std::is_const::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::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 - 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 void S2::h1(auto x) { called = 1; } template - void S2::h2(C x) { called = 2; } + void S2::h2(C auto x) { called = 2; } template void S2::h3(auto x) { called = 1; } template - void S2::h3(C x) { called = 2; } + void S2::h3(C auto x) { called = 2; } template template diff --git a/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C b/gcc/testsuite/g++.dg/concepts/inherit-ctor1.C index 98c260c89b95..e060da482917 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 - 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 76308ffb2120..58700b0964ed 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 - concept bool C() { return __is_class(T); } + concept C = __is_class(T); template struct S1 { diff --git a/gcc/testsuite/g++.dg/concepts/intro1.C b/gcc/testsuite/g++.dg/concepts/intro1.C index 0dd9b646a4db..da4f904b732d 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 - 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(); - s.f2(); - S1::f3(); - - return 0; -} - -template - void f1() requires C - { - } - -template - void S1::f2() requires C - { - } - -template - void S1::f3() requires C - { - } diff --git a/gcc/testsuite/g++.dg/concepts/intro2.C b/gcc/testsuite/g++.dg/concepts/intro2.C deleted file mode 100644 index 5c6906c8d352..000000000000 --- 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 - -template - concept bool C() { return __is_class(T); } - -template - concept bool P() { return true; } - -C{A} struct S1 -{ - P{B} int f1(); -}; - -struct S2 {}; - -int main() -{ - S1 s; - - assert(s.f1<10>() == sizeof(S2) + 10); - return 0; -} - -C{A} P{B} int S1::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 c92338e548dc..000000000000 --- 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 - concept bool C1 = true; - -template - concept bool C2 = true; - -C1{...A} void f1() {}; -C2{...A} void f2() {}; - -int main() -{ - f1(); - 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 5ddd16289346..000000000000 --- 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 - concept bool C1 = true; - -template - concept bool C2 = true; - -template - concept bool C3 = __is_class(T); - -template - concept bool C4() { return true; } -template - concept bool C4() { return true; } - -template - 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(); // { 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 cb1c5da78940..000000000000 --- 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 - 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 b718d134b2b4..000000000000 --- 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 - concept bool C = true; -} - -X::C{T} -void foo() {} - -int main() { foo(); } diff --git a/gcc/testsuite/g++.dg/concepts/intro7.C b/gcc/testsuite/g++.dg/concepts/intro7.C deleted file mode 100644 index 0c452a77b868..000000000000 --- 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