diff mbox series

[v2] c++: remove Concepts TS code

Message ID Zmx2REP9-KyI9Dbo@redhat.com
State New
Headers show
Series [v2] c++: remove Concepts TS code | expand

Commit Message

Marek Polacek June 14, 2024, 4:56 p.m. UTC
On Mon, Jun 10, 2024 at 10:23:37PM -0400, Jason Merrill wrote:
> On 6/10/24 11:13, Marek Polacek wrote:
> > On Mon, Jun 10, 2024 at 10:22:11AM -0400, Patrick Palka wrote:
> > > On Fri, 7 Jun 2024, Marek Polacek wrote:
> > > > @@ -3940,9 +3936,6 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
> > > >   	 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.  */
> > > 
> > > This comment should be removed too I think.
> > 
> > Removed in my local tree.
> > > > -      if (flag_concepts_ts && ppd->type_pack_expansion_p && is_auto (t)
> > > 
> > > (BTW this seems to be the only actual user of type_pack_expansion_p so we
> > > can in turn remove that field too.)
> > 
> > Oh neat.  I can do that as a follow-up, unless y'all think it should be
> > part of this patch.  Thanks,
> 
> It probably makes sense for it to be part of this patch.

OK, done.

> > One exception I'm aware of is template-introductions, as in:
> > 
> >   template<typename T>
> >   concept C = true;
> > 
> >   C{T} void foo ();
> > 
> > where we warn by default, but accept the code, and my patch does not
> > remove the support just yet.
> 
> I think let's go ahead and remove it as well.

Done as well.  I was able to remove quite a lot of functions.

> > +// ??? This used to be a link test with Concepts TS, but now we
> > +// get:
> > +// undefined reference to `_Z2f5ITk1C1XEvT_Q1DIS1_E'
> > +// undefined reference to `_Z2f6ITk1C1XEvT_Q1DIS1_E'
> > +// so it's a compile test only.
> 
> That means the test is failing, and we shouldn't in general change tests to
> stop testing the thing that fails; better to xfail.
> 
> In this case, however, C++20 doesn't establish the equivalence that it's
> testing; that's another thing that wasn't adopted from the Concepts TS.
> 
> Note that this area is in question currently; see CWG2802.  But I think the
> equivalence is unlikely to return.
> 
> So let's move main() to the bottom of the test and test for the ambiguity
> errors that we get because they aren't equivalent.

Thanks, done.

> > --- a/gcc/testsuite/g++.dg/concepts/pr67595.C
> > +++ /dev/null
> > @@ -1,14 +0,0 @@
> > -// { dg-do compile { target c++17_only } }
> > -// { dg-options "-fconcepts-ts" }
> > -
> > -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> 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);
> > -int main() { fn1(0); }  // { dg-error "" }
> 
> Why remove this test?  The main issue I see is that {new X}->X* needs to
> change to {new X}->convertible_to<X*> (or same_as)

Adjusted as suggested.

> > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
> > @@ -1,7 +1,5 @@
> >  // { dg-do compile { target c++20 } }
> > -// { dg-additional-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
> > -
> > -// Test conversion requirements (not in C++20)
> 
> This one could get the same adjustment instead of adding dg-errors.  Or
> perhaps the error could suggest that adjustment, and this testcase could
> check that?

Adjusted as well.  I don't think I understand what's going on here very
well.  There was:

  concept C = requires(T x) { { x.fn() } -> S1<T>; };

and with my patch:

  concept C = requires(T x) { { x.fn() } -> same_as<S1<T>>; };

so we're checking that the result of x.fn() is the same type as S1<T>.
Why doesn't plain "S1<T>" work?

Anyway, here's v2:

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
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: Remove -fconcepts-ts text.

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                           |   9 -
 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         |  44 +--
 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, 709 insertions(+), 2320 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


base-commit: 2830b0b8655f0d1a62b416af8ade31f5b96f0ffb

Comments

Jason Merrill July 3, 2024, 9:03 p.m. UTC | #1
On 6/14/24 12:56 PM, Marek Polacek wrote:
> On Mon, Jun 10, 2024 at 10:23:37PM -0400, Jason Merrill wrote:
>> On 6/10/24 11:13, Marek Polacek wrote:
>>> On Mon, Jun 10, 2024 at 10:22:11AM -0400, Patrick Palka wrote:
>>>> On Fri, 7 Jun 2024, Marek Polacek wrote:
>>>>> @@ -3940,9 +3936,6 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
>>>>>    	 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.  */
>>>>
>>>> This comment should be removed too I think.
>>>
>>> Removed in my local tree.
>>>>> -      if (flag_concepts_ts && ppd->type_pack_expansion_p && is_auto (t)
>>>>
>>>> (BTW this seems to be the only actual user of type_pack_expansion_p so we
>>>> can in turn remove that field too.)
>>>
>>> Oh neat.  I can do that as a follow-up, unless y'all think it should be
>>> part of this patch.  Thanks,
>>
>> It probably makes sense for it to be part of this patch.
> 
> OK, done.
> 
>>> One exception I'm aware of is template-introductions, as in:
>>>
>>>    template<typename T>
>>>    concept C = true;
>>>
>>>    C{T} void foo ();
>>>
>>> where we warn by default, but accept the code, and my patch does not
>>> remove the support just yet.
>>
>> I think let's go ahead and remove it as well.
> 
> Done as well.  I was able to remove quite a lot of functions.
> 
>>> +// ??? This used to be a link test with Concepts TS, but now we
>>> +// get:
>>> +// undefined reference to `_Z2f5ITk1C1XEvT_Q1DIS1_E'
>>> +// undefined reference to `_Z2f6ITk1C1XEvT_Q1DIS1_E'
>>> +// so it's a compile test only.
>>
>> That means the test is failing, and we shouldn't in general change tests to
>> stop testing the thing that fails; better to xfail.
>>
>> In this case, however, C++20 doesn't establish the equivalence that it's
>> testing; that's another thing that wasn't adopted from the Concepts TS.
>>
>> Note that this area is in question currently; see CWG2802.  But I think the
>> equivalence is unlikely to return.
>>
>> So let's move main() to the bottom of the test and test for the ambiguity
>> errors that we get because they aren't equivalent.
> 
> Thanks, done.
> 
>>> --- a/gcc/testsuite/g++.dg/concepts/pr67595.C
>>> +++ /dev/null
>>> @@ -1,14 +0,0 @@
>>> -// { dg-do compile { target c++17_only } }
>>> -// { dg-options "-fconcepts-ts" }
>>> -
>>> -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> 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);
>>> -int main() { fn1(0); }  // { dg-error "" }
>>
>> Why remove this test?  The main issue I see is that {new X}->X* needs to
>> change to {new X}->convertible_to<X*> (or same_as)
> 
> Adjusted as suggested.
> 
>>> +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires5.C
>>> @@ -1,7 +1,5 @@
>>>   // { dg-do compile { target c++20 } }
>>> -// { dg-additional-options "-fconcepts-ts -fconcepts-diagnostics-depth=2" }
>>> -
>>> -// Test conversion requirements (not in C++20)
>>
>> This one could get the same adjustment instead of adding dg-errors.  Or
>> perhaps the error could suggest that adjustment, and this testcase could
>> check that?
> 
> Adjusted as well.  I don't think I understand what's going on here very
> well.  There was:
> 
>    concept C = requires(T x) { { x.fn() } -> S1<T>; };
> 
> and with my patch:
> 
>    concept C = requires(T x) { { x.fn() } -> same_as<S1<T>>; };
> 
> so we're checking that the result of x.fn() is the same type as S1<T>.
> Why doesn't plain "S1<T>" work?

See the discussion of this change in wg21.link/p1452 .

> Anyway, here's v2:
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

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

I'd probably keep the documentation for now, modified to say that it was 
removed in GCC 15.

>  // Check equivalence of short- and longhand declarations.

Please add a comment that they are not equivalent in C++20.

> +++ b/gcc/testsuite/g++.dg/concepts/fn-concept3.C
> +static_assert(noexcept(C3<int>), "function concept should be treated as if noexcept(true) specified");

Let's update the message as well.

OK with those adjustments, thanks.

Jason
diff mbox series

Patch

diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index dfd8f6f0c48..a80372c8991 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 faaf9ee6350..f99670851ed 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 b067369fa7e..f87eefc8703 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 31d9ffef578..1b60ae4847b 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 ebf4255e546..5472cc51b8a 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 416c60b7311..5c5d0922918 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7482,7 +7482,6 @@  extern tree canonical_type_parameter		(tree);
 extern void push_access_scope			(tree);
 extern void pop_access_scope			(tree);
 extern bool check_template_shadow		(tree);
-extern bool check_auto_in_tmpl_args             (tree, tree);
 extern tree get_innermost_template_args		(tree, int);
 extern void maybe_begin_member_template_processing (tree);
 extern void maybe_end_member_template_processing (void);
@@ -8584,7 +8583,6 @@  extern hashval_t hash_placeholder_constraint	(tree);
 extern bool deduce_constrained_parameter        (tree, tree&, tree&);
 extern tree resolve_constraint_check            (tree);
 extern tree check_function_concept              (tree);
-extern tree finish_template_introduction        (tree, tree, location_t loc);
 extern bool valid_requirements_p                (tree);
 extern tree finish_concept_name                 (tree);
 extern tree finish_shorthand_constraint         (tree, tree);
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 03deb1493a4..88e5334d61e 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -1004,16 +1004,6 @@  member_like_constrained_friend_p (tree decl)
 static bool
 function_requirements_equivalent_p (tree newfn, tree oldfn)
 {
-  /* In the concepts TS, the combined constraints are compared.  */
-  if (cxx_dialect < cxx20)
-    {
-      tree ci1 = get_constraints (oldfn);
-      tree ci2 = get_constraints (newfn);
-      tree req1 = ci1 ? CI_ASSOCIATED_CONSTRAINTS (ci1) : NULL_TREE;
-      tree req2 = ci2 ? CI_ASSOCIATED_CONSTRAINTS (ci2) : NULL_TREE;
-      return cp_tree_equal (req1, req2);
-    }
-
   /* [temp.friend]/9 "Such a constrained friend function does not declare the
      same function as a declaration in any other scope."  So no need to
      actually compare the requirements.  */
@@ -10619,9 +10609,8 @@  grokfndecl (tree ctype,
 	 template shall be a definition. */
       if (ci
 	  && (block_local
-	      || (!flag_concepts_ts
-		  && (!processing_template_decl
-		      || (friendp && !memtmpl && !funcdef_flag)))))
+	      || !processing_template_decl
+	      || (friendp && !memtmpl && !funcdef_flag)))
 	{
 	  if (!friendp || !processing_template_decl)
 	    error_at (location, "constraints on a non-templated function");
@@ -11324,9 +11313,6 @@  grokvardecl (tree type,
 	}
       else
         DECL_DECLARED_CONCEPT_P (decl) = true;
-      if (!same_type_ignoring_top_level_qualifiers_p (type, boolean_type_node))
-	error_at (declspecs->locations[ds_type_spec],
-		  "concept must have type %<bool%>");
       if (TEMPLATE_PARMS_CONSTRAINTS (current_template_parms))
         {
           error_at (location, "a variable concept cannot be constrained");
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index e7409b856f1..d586381debe 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -16595,16 +16595,15 @@  cp_parser_decl_specifier_seq (cp_parser* parser,
 
           /* Warn for concept as a decl-specifier. We'll rewrite these as
              concept declarations later.  */
-          if (!flag_concepts_ts)
-            {
-	      cp_token *next = cp_lexer_peek_token (parser->lexer);
-	      if (next->keyword == RID_BOOL)
-		permerror (next->location, "the %<bool%> keyword is not "
-			   "allowed in a C++20 concept definition");
-	      else
-		error_at (token->location, "C++20 concept definition syntax "
-			  "is %<concept <name> = <expr>%>");
-            }
+	  {
+	    cp_token *next = cp_lexer_peek_token (parser->lexer);
+	    if (next->keyword == RID_BOOL)
+	      permerror (next->location, "the %<bool%> keyword is not "
+			 "allowed in a C++20 concept definition");
+	    else
+	      error_at (token->location, "C++20 concept definition syntax "
+			"is %<concept <name> = <expr>%>");
+	  }
 
 	  /* In C++20 a concept definition is just 'concept name = expr;'
 	     Support that syntax as a TS extension by pretending we've seen
@@ -18402,61 +18401,6 @@  cp_parser_template_parameter_list (cp_parser* parser)
   return end_template_parm_list (parameter_list);
 }
 
-/* Parse a introduction-list.
-
-   introduction-list:
-     introduced-parameter
-     introduction-list , introduced-parameter
-
-   introduced-parameter:
-     ...[opt] identifier
-
-   Returns a TREE_VEC of WILDCARD_DECLs.  If the parameter is a pack
-   then the introduced parm will have WILDCARD_PACK_P set.  In addition, the
-   WILDCARD_DECL will also have DECL_NAME set and token location in
-   DECL_SOURCE_LOCATION.  */
-
-static tree
-cp_parser_introduction_list (cp_parser *parser)
-{
-  vec<tree, va_gc> *introduction_vec = make_tree_vector ();
-
-  while (true)
-    {
-      bool is_pack = cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS);
-      if (is_pack)
-	cp_lexer_consume_token (parser->lexer);
-
-      tree identifier = cp_parser_identifier (parser);
-      if (identifier == error_mark_node)
-	break;
-
-      /* Build placeholder. */
-      tree parm = build_nt (WILDCARD_DECL);
-      DECL_SOURCE_LOCATION (parm)
-	= cp_lexer_peek_token (parser->lexer)->location;
-      DECL_NAME (parm) = identifier;
-      WILDCARD_PACK_P (parm) = is_pack;
-      vec_safe_push (introduction_vec, parm);
-
-      /* If the next token is not a `,', we're done.  */
-      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
-	break;
-      /* Otherwise, consume the `,' token.  */
-      cp_lexer_consume_token (parser->lexer);
-    }
-
-  /* Convert the vec into a TREE_VEC.  */
-  tree introduction_list = make_tree_vec (introduction_vec->length ());
-  unsigned int n;
-  tree parm;
-  FOR_EACH_VEC_ELT (*introduction_vec, n, parm)
-    TREE_VEC_ELT (introduction_list, n) = parm;
-
-  release_tree_vector (introduction_vec);
-  return introduction_list;
-}
-
 /* Given a declarator, get the declarator-id part, or NULL_TREE if this
    is an abstract declarator. */
 
@@ -19189,16 +19133,8 @@  cp_parser_template_id (cp_parser *parser,
   location_t combined_loc
     = make_location (token->location, token->location, parser->lexer);
 
-  /* Check for concepts autos where they don't belong.  We could
-     identify types in some cases of identifier TEMPL, looking ahead
-     for a CPP_SCOPE, but that would buy us nothing: we accept auto in
-     types.  We reject them in functions, but if what we have is an
-     identifier, even with none_type we can't conclude it's NOT a
-     type, we have to wait for template substitution.  */
-  if (flag_concepts && check_auto_in_tmpl_args (templ, arguments))
-    template_id = error_mark_node;
   /* Build a representation of the specialization.  */
-  else if (identifier_p (templ))
+  if (identifier_p (templ))
     template_id = build_min_nt_loc (combined_loc,
 				    TEMPLATE_ID_EXPR,
 				    templ, arguments);
@@ -20520,10 +20456,9 @@  cp_parser_simple_type_specifier (cp_parser* parser,
 			 "only available with "
 			 "%<-std=c++14%> or %<-std=gnu++14%>");
 	    }
-	  else if (!flag_concepts_ts && parser->in_template_argument_list_p)
-	    pedwarn (token->location, 0,
-		     "use of %<auto%> in template argument "
-		     "only available with %<-fconcepts-ts%>");
+	  else if (parser->in_template_argument_list_p)
+	    error_at (token->location,
+		     "use of %<auto%> in template argument");
 	  else if (!flag_concepts)
 	    pedwarn (token->location, 0,
 		     "use of %<auto%> in parameter declaration "
@@ -20866,10 +20801,7 @@  cp_parser_simple_type_specifier (cp_parser* parser,
 
   TENTATIVE is true if the type-specifier parsing is tentative; in that case,
   don't give an error if TMPL isn't a valid type-constraint, as the template-id
-  might actually be a concept-check,
-
-  Note that the Concepts TS allows the auto or decltype(auto) to be
-  omitted in a constrained-type-specifier.  */
+  might actually be a concept-check.  */
 
 static tree
 cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
@@ -20900,38 +20832,29 @@  cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
   if (con == error_mark_node)
     return error_mark_node;
 
-  /* As per the standard, require auto or decltype(auto), except in some
-     cases (template parameter lists, -fconcepts-ts enabled).  */
+  /* As per the standard, require auto or decltype(auto).  */
   cp_token *placeholder = NULL, *close_paren = NULL;
-  if (cxx_dialect >= cxx20)
+  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
+    placeholder = cp_lexer_consume_token (parser->lexer);
+  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DECLTYPE))
     {
-      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
-	placeholder = cp_lexer_consume_token (parser->lexer);
-      else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DECLTYPE))
-	{
-	  placeholder = cp_lexer_consume_token (parser->lexer);
-	  matching_parens parens;
-	  parens.require_open (parser);
-	  cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
-	  close_paren = parens.require_close (parser);
-	}
+      placeholder = cp_lexer_consume_token (parser->lexer);
+      matching_parens parens;
+      parens.require_open (parser);
+      cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
+      close_paren = parens.require_close (parser);
     }
 
   /* A type constraint constrains a contextually determined type or type
-     parameter pack. However, the Concepts TS does allow concepts
-     to introduce non-type and template template parameters.  */
+     parameter pack.  */
   if (TREE_CODE (proto) != TYPE_DECL)
     {
-      if (!flag_concepts_ts
-	  || !processing_template_parmlist)
+      if (!tentative)
 	{
-	  if (!tentative)
-	    {
-	      error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
-	      inform (DECL_SOURCE_LOCATION (con), "concept defined here");
-	    }
-	  return error_mark_node;
+	  error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
+	  inform (DECL_SOURCE_LOCATION (con), "concept defined here");
 	}
+      return error_mark_node;
     }
 
   /* In a template parameter list, a type-parameter can be introduced
@@ -20949,9 +20872,7 @@  cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
     }
 
   /* Diagnose issues placeholder issues.  */
-  if (!flag_concepts_ts
-      && !parser->in_result_type_constraint_p
-      && !placeholder)
+  if (!parser->in_result_type_constraint_p && !placeholder)
     {
       if (tentative)
 	/* Perhaps it's a concept-check expression (c++/91073).  */
@@ -25216,14 +25137,11 @@  cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
     abstract_declarator = NULL;
 
   bool auto_typeid_ok = false;
-  /* The concepts TS allows 'auto' as a type-id.  */
-  if (flag_concepts_ts)
-    auto_typeid_ok = !parser->in_type_id_in_expr_p;
   /* DR 625 prohibits use of auto as a template-argument.  We allow 'auto'
      outside the template-argument-list context here only for the sake of
      diagnostic: grokdeclarator then can emit a better error message for
      e.g. using T = auto.  */
-  else if (flag_concepts)
+  if (flag_concepts)
     auto_typeid_ok = (!parser->in_type_id_in_expr_p
 		      && !parser->in_template_argument_list_p);
 
@@ -25297,7 +25215,7 @@  cp_parser_template_type_arg (cp_parser *parser)
   parser->type_definition_forbidden_message = saved_message;
   /* cp_parser_type_id_1 checks for auto, but only for
      ->auto_is_implicit_function_template_parm_p.  */
-  if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r))
+  if (cxx_dialect >= cxx14 && type_uses_auto (r))
     {
       error ("invalid use of %<auto%> in template argument");
       r = error_mark_node;
@@ -31589,8 +31507,7 @@  cp_parser_constraint_logical_or_expression (cp_parser *parser, bool lambda_p)
   return lhs;
 }
 
-/* Parse the expression after a requires-clause. This has a different grammar
-    than that in the concepts TS.  */
+/* Parse the expression after a requires-clause.  */
 
 static tree
 cp_parser_requires_clause_expression (cp_parser *parser, bool lambda_p)
@@ -31675,10 +31592,7 @@  cp_parser_requires_clause_opt (cp_parser *parser, bool lambda_p)
   else
     cp_lexer_consume_token (parser->lexer);
 
-  if (!flag_concepts_ts)
-    return cp_parser_requires_clause_expression (parser, lambda_p);
-  else
-    return cp_parser_constraint_expression (parser);
+  return cp_parser_requires_clause_expression (parser, lambda_p);
 }
 
 /*---------------------------------------------------------------------------
@@ -32053,7 +31967,7 @@  cp_parser_compound_requirement (cp_parser *parser)
 	      return error_mark_node;
 	    }
 	}
-      else if (!flag_concepts_ts)
+      else
 	/* P1452R2 removed the trailing-return-type option.  */
 	error_at (type_loc,
 		  "return-type-requirement is not a type-constraint");
@@ -33199,110 +33113,6 @@  cp_parser_template_declaration_after_parameters (cp_parser* parser,
     vec_safe_push (unparsed_funs_with_definitions, decl);
 }
 
-/* Parse a template introduction header for a template-declaration.  Returns
-   false if tentative parse fails.  */
-
-static bool
-cp_parser_template_introduction (cp_parser* parser, bool member_p)
-{
-  cp_parser_parse_tentatively (parser);
-
-  tree saved_scope = parser->scope;
-  tree saved_object_scope = parser->object_scope;
-  tree saved_qualifying_scope = parser->qualifying_scope;
-  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
-
-  cp_token *start_token = cp_lexer_peek_token (parser->lexer);
-
-  /* In classes don't parse valid unnamed bitfields as invalid
-     template introductions.  */
-  if (member_p)
-    parser->colon_corrects_to_scope_p = false;
-
-  /* Look for the optional `::' operator.  */
-  cp_parser_global_scope_opt (parser,
-			      /*current_scope_valid_p=*/false);
-  /* Look for the nested-name-specifier.  */
-  cp_parser_nested_name_specifier_opt (parser,
-				       /*typename_keyword_p=*/false,
-				       /*check_dependency_p=*/true,
-				       /*type_p=*/false,
-				       /*is_declaration=*/false);
-
-  cp_token *token = cp_lexer_peek_token (parser->lexer);
-  tree concept_name = cp_parser_identifier (parser);
-
-  /* Look up the concept for which we will be matching
-     template parameters.  */
-  tree tmpl_decl = cp_parser_lookup_name_simple (parser, concept_name,
-						 token->location);
-  parser->scope = saved_scope;
-  parser->object_scope = saved_object_scope;
-  parser->qualifying_scope = saved_qualifying_scope;
-  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
-
-  if (concept_name == error_mark_node
-      || (seen_error () && !concept_definition_p (tmpl_decl)))
-    cp_parser_simulate_error (parser);
-
-  /* Look for opening brace for introduction.  */
-  matching_braces braces;
-  braces.require_open (parser);
-  location_t open_loc = input_location;
-
-  if (!cp_parser_parse_definitely (parser))
-    return false;
-
-  push_deferring_access_checks (dk_deferred);
-
-  /* Build vector of placeholder parameters and grab
-     matching identifiers.  */
-  tree introduction_list = cp_parser_introduction_list (parser);
-
-  /* Look for closing brace for introduction.  */
-  if (!braces.require_close (parser))
-    return true;
-
-  /* The introduction-list shall not be empty.  */
-  int nargs = TREE_VEC_LENGTH (introduction_list);
-  if (nargs == 0)
-    {
-      /* In cp_parser_introduction_list we have already issued an error.  */
-      return true;
-    }
-
-  if (tmpl_decl == error_mark_node)
-    {
-      cp_parser_name_lookup_error (parser, concept_name, tmpl_decl, NLE_NULL,
-				   token->location);
-      return true;
-    }
-
-  /* Build and associate the constraint.  */
-  location_t introduction_loc = make_location (open_loc,
-					       start_token->location,
-					       parser->lexer);
-  tree parms = finish_template_introduction (tmpl_decl,
-					     introduction_list,
-					     introduction_loc);
-  if (parms && parms != error_mark_node)
-    {
-      if (!flag_concepts_ts)
-	pedwarn (introduction_loc, 0, "template-introductions"
-		 " are not part of C++20 concepts; use %qs to enable",
-		 "-fconcepts-ts");
-
-      cp_parser_template_declaration_after_parameters (parser, parms,
-						       member_p);
-      return true;
-    }
-
-  if (parms == NULL_TREE)
-    error_at (token->location, "no matching concept for template-introduction");
-
-  return true;
-}
-
 /* Parse a normal template-declaration following the template keyword.  */
 
 static void
@@ -33394,8 +33204,6 @@  cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
       cp_parser_explicit_template_declaration (parser, member_p);
       return true;
     }
-  else if (flag_concepts)
-    return cp_parser_template_introduction (parser, member_p);
 
   return false;
 }
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 607753ae6b7..6cc0b155903 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 = &parameter_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 = &parameter_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 = &parameter_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 = &parameter_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 = &parameter_packs;
   ppd.visited = new hash_set<tree>;
-  ppd.type_pack_expansion_p = false;
 
   fixed_parameter_pack_p_1 (parm, &ppd);
 
@@ -17353,15 +17326,6 @@  tsubst_qualified_id (tree qualified_id, tree args,
 
   if (is_template)
     {
-      /* We may be repeating a check already done during parsing, but
-	 if it was well-formed and passed then, it will pass again
-	 now, and if it didn't, we wouldn't have got here.  The case
-	 we want to catch is when we couldn't tell then, and can now,
-	 namely when templ prior to substitution was an
-	 identifier.  */
-      if (flag_concepts && check_auto_in_tmpl_args (expr, template_args))
-	return error_mark_node;
-
       if (variable_template_p (expr))
 	expr = lookup_and_finish_template_variable (expr, template_args,
 						    complain);
@@ -29627,63 +29591,6 @@  auto_hash::equal (tree t1, tree t2)
   return equivalent_placeholder_constraints (c1, c2);
 }
 
-/* for_each_template_parm callback for extract_autos: if t is a (possibly
-   constrained) auto, add it to the vector.  */
-
-static int
-extract_autos_r (tree t, void *data)
-{
-  hash_table<auto_hash> &hash = *(hash_table<auto_hash>*)data;
-  if (is_auto (t) && !template_placeholder_p (t))
-    {
-      /* All the autos were built with index 0; fix that up now.  */
-      tree *p = hash.find_slot (t, INSERT);
-      int idx;
-      if (*p)
-	/* If this is a repeated constrained-type-specifier, use the index we
-	   chose before.  */
-	idx = TEMPLATE_TYPE_IDX (*p);
-      else
-	{
-	  /* Otherwise this is new, so use the current count.  */
-	  *p = t;
-	  idx = hash.elements () - 1;
-	}
-      if (idx != TEMPLATE_TYPE_IDX (t))
-	{
-	  gcc_checking_assert (TEMPLATE_TYPE_IDX (t) == 0);
-	  gcc_checking_assert (TYPE_CANONICAL (t) != t);
-	  TEMPLATE_TYPE_IDX (t) = idx;
-	  TYPE_CANONICAL (t) = canonical_type_parameter (t);
-	}
-    }
-
-  /* Always keep walking.  */
-  return 0;
-}
-
-/* Return a TREE_VEC of the 'auto's used in type under the Concepts TS, which
-   says they can appear anywhere in the type.  */
-
-static tree
-extract_autos (tree type)
-{
-  hash_set<tree> visited;
-  hash_table<auto_hash> hash (2);
-
-  for_each_template_parm (type, extract_autos_r, &hash, &visited, true);
-
-  tree tree_vec = make_tree_vec (hash.elements());
-  for (tree elt : hash)
-    {
-      unsigned i = TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (elt));
-      TREE_VEC_ELT (tree_vec, i)
-	= build_tree_list (NULL_TREE, TYPE_NAME (elt));
-    }
-
-  return tree_vec;
-}
-
 /* The stem for deduction guide names.  */
 const char *const dguide_base = "__dguide_";
 
@@ -31216,16 +31123,9 @@  do_auto_deduction (tree type, tree init, tree auto_node,
 	return error_mark_node;
 
       tree parms = build_tree_list (NULL_TREE, type);
-      tree tparms;
-
-      if (flag_concepts_ts)
-	tparms = extract_autos (type);
-      else
-	{
-	  tparms = make_tree_vec (1);
-	  TREE_VEC_ELT (tparms, 0)
-	    = build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
-	}
+      tree tparms = make_tree_vec (1);
+      TREE_VEC_ELT (tparms, 0)
+	= build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
 
       targs = make_tree_vec (TREE_VEC_LENGTH (tparms));
       int val = type_unification_real (tparms, targs, parms, &init, 1, 0,
@@ -31437,66 +31337,7 @@  type_uses_auto (tree type)
   if (PACK_EXPANSION_P (type))
     type = PACK_EXPANSION_PATTERN (type);
 
-  if (flag_concepts_ts)
-    {
-      /* The Concepts TS allows multiple autos in one type-specifier; just
-	 return the first one we find, do_auto_deduction will collect all of
-	 them.  */
-      if (uses_template_parms (type))
-	return for_each_template_parm (type, is_auto_r, /*data*/NULL,
-				       /*visited*/NULL, /*nondeduced*/false);
-      else
-	return NULL_TREE;
-    }
-  else
-    return find_type_usage (type, is_auto);
-}
-
-/* Report ill-formed occurrences of auto types in ARGUMENTS.  If
-   concepts are enabled, auto is acceptable in template arguments, but
-   only when TEMPL identifies a template class.  Return TRUE if any
-   such errors were reported.  */
-
-bool
-check_auto_in_tmpl_args (tree tmpl, tree args)
-{
-  if (!flag_concepts_ts)
-    /* Only the concepts TS allows 'auto' as a type-id; it'd otherwise
-       have already been rejected by the parser more generally.  */
-    return false;
-
-  /* If there were previous errors, nevermind.  */
-  if (!args || TREE_CODE (args) != TREE_VEC)
-    return false;
-
-  /* If TMPL is an identifier, we're parsing and we can't tell yet
-     whether TMPL is supposed to be a type, a function or a variable.
-     We'll only be able to tell during template substitution, so we
-     expect to be called again then.  If concepts are enabled and we
-     know we have a type, we're ok.  */
-  if (identifier_p (tmpl)
-      || (DECL_P (tmpl)
-	  &&  (DECL_TYPE_TEMPLATE_P (tmpl)
-	       || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))))
-    return false;
-
-  /* Quickly search for any occurrences of auto; usually there won't
-     be any, and then we'll avoid allocating the vector.  */
-  if (!type_uses_auto (args))
-    return false;
-
-  bool errors = false;
-
-  tree vec = extract_autos (args);
-  for (int i = 0; i < TREE_VEC_LENGTH (vec); i++)
-    {
-      tree xauto = TREE_VALUE (TREE_VEC_ELT (vec, i));
-      error_at (DECL_SOURCE_LOCATION (xauto),
-		"invalid use of %qT in template argument", xauto);
-      errors = true;
-    }
-
-  return errors;
+  return find_type_usage (type, is_auto);
 }
 
 /* Recursively walk over && expressions searching for EXPR. Return a reference
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5d7a87fde86..32ec82ed1ea 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -3216,20 +3216,11 @@  exhaustion is signalled by throwing @code{std::bad_alloc}.  See also
 @samp{new (nothrow)}.
 
 @opindex fconcepts
-@opindex fconcepts-ts
 @item -fconcepts
-@itemx -fconcepts-ts
 Enable support for the C++ Concepts feature for constraining template
 arguments.  With @option{-std=c++20} and above, Concepts are part of
 the language standard, so @option{-fconcepts} defaults to on.
 
-Some constructs that were allowed by the earlier C++ Extensions for
-Concepts Technical Specification, ISO 19217 (2015), but didn't make it
-into the standard, can additionally be enabled by
-@option{-fconcepts-ts}.  The option @option{-fconcepts-ts} was deprecated
-in GCC 14 and may be removed in GCC 15; users are expected to convert
-their code to C++20 concepts.
-
 @opindex fconstexpr-depth
 @item -fconstexpr-depth=@var{n}
 Set the maximum nested evaluation depth for C++11 constexpr functions
diff --git a/gcc/testsuite/g++.dg/concepts/auto1.C b/gcc/testsuite/g++.dg/concepts/auto1.C
deleted file mode 100644
index abf7886c9f6..00000000000
--- 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 868a56cf315..5c91cc08f2e 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 6c984550229..00000000000
--- 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 f1d653efd87..5538f2ebc01 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 1f6d72e54cc..00000000000
--- 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 3cbf5dd8dfc..26c9e9e7bca 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 fc60dc871c2..f4b0d969157 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 7f427d053b8..5d4b1499047 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 5f8ece96543..02d670ebe9f 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 a1c5e166e55..77f7203b41f 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 fb48567249f..43af4191a48 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 96038fd3dfc..0d10ce1ea9f 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 d510fe00f2c..4350f59dc5c 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 207c36c320e..2f299b37357 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 c22a7827eba..ae58496d1ee 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 a5d0c1864c0..471833027e4 100644
--- a/gcc/testsuite/g++.dg/concepts/equiv.C
+++ b/gcc/testsuite/g++.dg/concepts/equiv.C
@@ -1,35 +1,35 @@ 
-// { dg-do link { target c++17_only } }
-// { dg-options "-fconcepts-ts" }
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts" }
 
 // Check equivalence of short- and longhand declarations.
 
 template<typename T>
-  concept bool C() { return __is_class(T); }
+  concept C = __is_class(T);
 
 template<typename T>
-  concept bool D() { return __is_empty(T); }
+  concept D = __is_empty(T);
 
 struct X { } x;
 
-void f1(C x);
+void f1(C auto x);
 template<C T> void f2(T x);
-void f3(C x);
-template<C T> void f4(T x) requires D<T>();
-template<C T> void f5(T x) requires D<T>();
-template<C T> void f6(T x) requires D<T>();
+void f3(C auto x);
+template<C T> void f4(T x) requires D<T>;
+template<C T> void f5(T x) requires D<T>;
+template<C T> void f6(T x) requires D<T>;
+
+template<typename T> requires C<T> void f1(T x) { }
+template<typename T> requires C<T> void f2(T x) { }
+template<C T> void f3(T x) { }
+template<typename T> requires C<T> void f4(T x) requires D<T> { }
+template<typename T> requires C<T> and D<T> void f5(T x) { }
+template<typename T> void f6(T x) requires C<T> and D<T> { }
 
 int main() {
-  f1(x);
-  f2(x);
-  f3(x);
-  f4(x);
-  f5(x);
-  f6(x);
+  f1(x);    // { dg-error "ambiguous" }
+  f2(x);    // { dg-error "ambiguous" }
+  f3(x);    // { dg-error "ambiguous" }
+  f4(x);    // { dg-error "ambiguous" }
+  f5(x);    // { dg-error "ambiguous" }
+  f6(x);    // { dg-error "ambiguous" }
 }
-
-template<typename T> requires C<T>() void f1(T x) { }
-template<typename T> requires C<T>() void f2(T x) { }
-template<C T> void f3(T x) { }
-template<typename T> requires C<T>() void f4(T x) requires D<T>() { }
-template<typename T> requires C<T>() and D<T>() void f5(T x) { }
-template<typename T> void f6(T x) requires C<T>() and D<T>() { }
diff --git a/gcc/testsuite/g++.dg/concepts/equiv2.C b/gcc/testsuite/g++.dg/concepts/equiv2.C
index 48a266498f9..0121fb8039f 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 3da0c962888..90ee7cecf85 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 2f7aafc8b6b..c0eb4e545ff 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 a2d340dfaca..412e7e9e03e 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 4908d11d56d..00000000000
--- 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 28765054b5c..799e85de955 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 88ed5a8e8b2..d4c7a5a3890 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>), "function 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 e22cbf70a46..16c3593613e 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 83099de90a1..e19ac35527f 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 e0ac36ff3dd..fbf970ed9ee 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 3e076f62ee8..546fa7eb85f 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 64186778f28..59fd44420bc 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 3decf4e38ee..8b3f0896631 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 57c4cfbd016..e948d03139e 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 1994feca84b..ac893ecd318 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 594270f5178..16c64a3be3a 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 51edd2fc539..63c3b5a79c6 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 e4909eb50bf..698aad6e201 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 983b37092f8..9af1794b49e 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 98c260c89b9..e060da48291 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 76308ffb212..58700b0964e 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 0dd9b646a4d..da4f904b732 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 5c6906c8d35..00000000000
--- 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 c92338e548d..00000000000
--- 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 5ddd1628934..00000000000
--- 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 cb1c5da7894..00000000000
--- 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 b718d134b2b..00000000000
--- 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 0c452a77b86..00000000000
--- 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 ea227433d2d..9553dd1d792 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 09c9d4fe8ef..712f26d6196 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 089f40fe640..36b8cab0d92 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 954c072ee6c..c772d1b9ea5 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 f1c3b9c6917..e5ff81235f0 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 6b79ef6401d..d9d0f95b0fd 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 16451611b2c..5bd7022ca5e 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 21a6b318ff6..b01336a1c9c 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 c7f62d1aa4c..767cca6a054 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 650d10eba5f..e65df6b2b87 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 69091dcfdb7..76a42144a86 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 cf34911e787..9a4615d61b9 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 76e6f6faefc..600b48b3076 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 75f0ea0e4ea..e0f8d5ade01 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 33122d2ddb0..741296612da 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 ff6a8980700..e03d2a4c579 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 e76aec15809..9c9a77a84f5 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 351a6465df1..63b3d1dff78 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 8da43aff49c..812372616c9 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 66ca52bdfe1..fcafd2dd616 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 72f2aca8915..b9596115bc0 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 32a15543310..60ff4214fea 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 b376a490298..76af3d6241e 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 81d08180a29..4edc55ffcf8 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 dc6983a6eaa..8c74770e69b 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 2e6bd2c04e0..285578b02b8 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 8f8ad6315ba..190248ac196 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 019a9333ece..fc43426b22e 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 3a3b3405bff..442e5e21bb7 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 0ef2322cad2..ab1783816ff 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 b4483ebca89..d19a91330e4 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 7ae9f36c2d0..3a352aa6dba 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 cc7f4af47c6..b5dd6004b46 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 d2270df1727..04298f47a92 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 026fe9f4165..441fbacd321 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 4ac578f88bc..b69d7d8d6a2 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 2eb419aa945..c564c079c77 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 662511eee03..0b3899a717c 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 c590f28ee81..aad6db02562 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 1776b951113..93380ae5686 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 07c2401a785..e8a20bb6c59 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 1dfa2e6000b..1c0612b0449 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 bec97e98352..79e9472ef2f 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 cd3acf77876..7ad79190483 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 97f80cfcfa8..360817b2f41 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 d59d4f95bfb..1b63c467bb3 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 f8d99ffe006..1b3538dceea 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 937098d394f..4754193c029 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 e37ad28c1bc..1f39b93fead 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 92f42982a38..f649ceb81cb 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 5399780cfbf..338251ce954 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 fad43be6c5b..c5d175d46a3 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 5087344d2c9..352407d8c67 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 530cb333f38..cd82a84e7fe 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 392492214e2..b0e91906fef 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 27083371ae1..625d9efc0b7 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 c3c5c235455..cd03f6e644f 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 5ee5c2dac8f..58c50020937 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 64cd9d2d336..9f5051fe82d 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 693237fa783..8807a8cb868 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 b42ce8b7c30..e0b869caa95 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 b809553c07a..83dee7069fa 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 2dd46dae6d7..0085191e2bd 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 9fc90ff39a6..95e9c32f8f1 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 324b3ad8b37..46bc759fdf2 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 1df563b341c..2b5d012ade6 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 7d7c716cfec..af2fb8aa02f 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 447b149b80c..6cf4f2111c4 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 5fdd64eb26f..54f88557577 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 1a0008e7a98..f083ba57dd0 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 92e89da5451..a39977ece3c 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 81a671c7b1a..81b4fdae153 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 01a42a4e73f..81b258d4dfd 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 635a1688999..fb0042cf32b 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 d351b4594ae..00000000000
--- 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 f32ca63d5ee..0c836a93ef6 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 6fb430d90a3..0f6c764959b 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 28be9e9e0ea..2d16d053e52 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 976efe67c46..524eadbf5dd 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 a116cac4ea4..00000000000
--- 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 5942ff19327..00000000000
--- 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 6f7ed1ffee4..00000000000
--- 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 cc49ff4fb27..00000000000
--- 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 06244882167..00000000000
--- 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 8aede575f75..00000000000
--- 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 eb8a6ad9375..7c23d244e6d 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 25fea793355..1ffeccb9cfa 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