On Tue, 3 Feb 2026, Patrick Palka wrote:

> 
> 
> On Tue, 3 Feb 2026, Patrick Palka wrote:
> 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
> > OK for trunk?  This is an update of the patch
> > https://gcc.gnu.org/pipermail/gcc-patches/2025-March/679588.html
> > that sidesteps the auto*/auto& issue.
> 
> FWIW Clang rejects constrained auto*/auto& NTTPs outright:
>   error: constrained placeholder types other than
>          simple 'auto' on non-type template parameters not supported yet

This incidentally fixes

  Bug 120136 - [13/14/15/16 Regression] internal compiler error: tree check: 
accessed elt 1 of 'tree_vec' with -1 elts in add_to_template_args, at 
cp/pt.cc:612 
  Bug 120142 - [13/14/15/16 regression] internal compiler error: in tsubst, at 
cp/pt.cc:16670 since r13-6971-ga5de246535db1b
  Bug 122204 - ICE when deducing a concept-constrained constant template 
parameter

since it means we sidestep do_auto_deduction's buggy handling of outer
template arguments when checking constraints on an auto.

> 
> > 
> > -- >8 --
> > 
> > According to [temp.param], the constraint on an auto NTTP is an
> > associated constraint and so should be checked as part of satisfaction
> > of the overall associated constraints, but we currently don't treat
> > them as part of the template's associated constraints and instead
> > check them separately during template argument coercion/deduction.
> > 
> > Fixing this is mostly a matter of storing the constrained auto's
> > type-constraint inside TEMPLATE_PARM_CONSTRAINTS instead of
> > PLACEHOLDER_TYPE_CONSTRAINTS and teaching the relevant subroutines
> > to recognize constrained auto NTTPs (alongside constrained type
> > parameters).
> > 
> > While this is straightfoward for "simple" constrained autos, it was
> > later noticed that for e.g. 'C auto* P' or 'D auto& Q' it's not clear at
> > all how to express their type-constraint as an associated constraint.
> > For P an option would be C<decltype(*P)>, but for Q it's not clear how
> > to pass the referenced type to C.  C<decltype(auto(Q))> would not be
> > right because it'd wrongly decay function/array types.
> > 
> > So this patch sidesteps this question by preserving the existing
> > behavior for "non-simple" constrained auto (i.e. don't add them to the
> > associated constraints, and continue checking them during
> > do_auto_deduction).  The simple case is by far the most common anyway.
> > 
> > The main observeable difference with this change is that such
> > constrained auto NTTPs are now involved in the "more constrained"
> > determination during partial ordering.
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * constraint.cc (finish_shorthand_constraint): Add is_non_type
> >     parameter.  Handle constrained (auto) NTTPS.
> >     * cp-tree.h (copy_template_args): Declare.
> >     (finish_shorthand_constraint): Adjust declaration.
> >     * mangle.cc (write_template_param_decl): Obtain constraints of
> >     an auto NTTP through TEMPLATE_PARM_CONSTRAINTS instead of
> >     PLACEHOLDER_TYPE_CONSTRAINTS.
> >     * parser.cc (cp_parser_constrained_type_template_parm): Inline
> >     into its only caller and remove.
> >     (cp_parser_constrained_non_type_template_parm): Likewise.
> >     (finish_constrained_parameter): Simplify after the above.  Replace
> >     the type of an ordinary constrained (auto) NTTP with a
> >     non-constrained one and set TEMPLATE_PARM_CONSTRAINTS for it.
> >     (cp_parser_template_parameter): Dispatch to
> >     finish_constrained_parameter for a constrained auto NTTP.
> >     * pt.cc (process_template_parm): Pass is_non_type to
> >     finish_shorthand_constraint.  Use TEMPLATE_PARM_CONSTRAINTS
> >     instead of TREE_TYPE for clarity.
> >     (copy_template_args): Remove static.
> >     (make_constrained_placeholder_type): Return the type not the
> >     TYPE_NAME for consistency with make_auto_1 etc.
> >     (do_auto_deduction): Assert we no longer see simple constrained
> >     autos during coercion/deduction.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/cpp2a/concepts-placeholder12.C: Adjust expected error
> >     upon constrained auto NTTP satisfaction failure.
> >     * g++.dg/cpp2a/concepts-pr97093.C: Likewise.
> >     * g++.dg/cpp2a/concepts-template-parm2.C: Likewise.
> >     * g++.dg/cpp2a/concepts-template-parm6.C: Likewise.
> >     * g++.dg/cpp2a/concepts-template-parm12.C: New test.
> > ---
> >  gcc/cp/constraint.cc                          | 36 +++++++--
> >  gcc/cp/cp-tree.h                              |  3 +-
> >  gcc/cp/mangle.cc                              |  4 +-
> >  gcc/cp/parser.cc                              | 80 +++++++++++--------
> >  gcc/cp/pt.cc                                  | 15 ++--
> >  .../g++.dg/cpp2a/concepts-placeholder12.C     |  4 +-
> >  gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C |  2 +-
> >  .../g++.dg/cpp2a/concepts-template-parm12.C   | 31 +++++++
> >  .../g++.dg/cpp2a/concepts-template-parm2.C    |  2 +-
> >  .../g++.dg/cpp2a/concepts-template-parm6.C    |  2 +-
> >  10 files changed, 126 insertions(+), 53 deletions(-)
> >  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-template-parm12.C
> > 
> > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> > index 0b91e8785631..a48c6ea770f0 100644
> > --- a/gcc/cp/constraint.cc
> > +++ b/gcc/cp/constraint.cc
> > @@ -1218,7 +1218,7 @@ build_constrained_parameter (tree cnc, tree proto, 
> > tree args)
> >     done only after the requires clause has been parsed (or not).  */
> >  
> >  tree
> > -finish_shorthand_constraint (tree decl, tree constr)
> > +finish_shorthand_constraint (tree decl, tree constr, bool is_non_type)
> >  {
> >    /* No requirements means no constraints.  */
> >    if (!constr)
> > @@ -1227,9 +1227,26 @@ finish_shorthand_constraint (tree decl, tree constr)
> >    if (error_operand_p (constr))
> >      return NULL_TREE;
> >  
> > -  tree proto = CONSTRAINED_PARM_PROTOTYPE (constr);
> > -  tree con = CONSTRAINED_PARM_CONCEPT (constr);
> > -  tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
> > +  tree proto, con, args;
> > +  if (is_non_type)
> > +    {
> > +      /* This function should not see constrained auto&, auto* NTTPs, and a
> > +    simple constrained auto NTTP type should have been replaced by
> > +    ordinary auto at this point; see finish_constrained_parameter.  */
> > +      gcc_checking_assert (is_auto (TREE_TYPE (decl))
> > +                      && !is_constrained_auto (TREE_TYPE (decl)));
> > +      gcc_checking_assert (TREE_CODE (constr) == TEMPLATE_ID_EXPR);
> > +      tree tmpl = TREE_OPERAND (constr, 0);
> > +      proto = concept_prototype_parameter (tmpl);
> > +      con = DECL_TEMPLATE_RESULT (tmpl);
> > +      args = TREE_OPERAND (constr, 1);
> > +    }
> > +  else
> > +    {
> > +      proto = CONSTRAINED_PARM_PROTOTYPE (constr);
> > +      con = CONSTRAINED_PARM_CONCEPT (constr);
> > +      args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
> > +    }
> >  
> >    bool variadic_concept_p = template_parameter_pack_p (proto);
> >    bool declared_pack_p = template_parameter_pack_p (decl);
> > @@ -1243,7 +1260,16 @@ finish_shorthand_constraint (tree decl, tree constr)
> >  
> >    /* Build the concept constraint-expression.  */
> >    tree tmpl = DECL_TI_TEMPLATE (con);
> > -  tree check = build_concept_check (tmpl, arg, args, tf_warning_or_error);
> > +  tree check;
> > +  if (is_non_type)
> > +    {
> > +      arg = finish_decltype_type (arg, /*id_expr=*/true, 
> > tf_warning_or_error);
> > +      args = copy_template_args (args);
> > +      TREE_VEC_ELT (args, 0) = arg;
> > +      check = build_concept_check (tmpl, args, tf_warning_or_error);
> > +    }
> > +  else
> > +    check = build_concept_check (tmpl, arg, args, tf_warning_or_error);
> >  
> >    /* Make the check a fold-expression if needed.
> >       Use UNKNOWN_LOCATION so write_template_args can tell the
> > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> > index 59ab4e40430d..b784dd45a595 100644
> > --- a/gcc/cp/cp-tree.h
> > +++ b/gcc/cp/cp-tree.h
> > @@ -8112,6 +8112,7 @@ extern bool is_specialization_of_friend               
> > (tree, tree);
> >  extern bool comp_template_args                     (tree, tree, tree * = 
> > NULL,
> >                                              tree * = NULL);
> >  extern int template_args_equal                  (tree, tree);
> > +extern tree copy_template_args                     (tree);
> >  extern tree maybe_process_partial_specialization (tree);
> >  extern tree most_specialized_instantiation (tree);
> >  extern tree most_specialized_partial_spec       (tree, tsubst_flags_t, 
> > bool = false);
> > @@ -9175,7 +9176,7 @@ extern tree build_concept_check                 
> > (tree, tree, tree, tsubst_flags_
> >  extern tree build_constrained_parameter         (tree, tree, tree = 
> > NULL_TREE);
> >  extern bool equivalent_placeholder_constraints  (tree, tree);
> >  extern hashval_t iterative_hash_placeholder_constraint     (tree, 
> > hashval_t);
> > -extern tree finish_shorthand_constraint         (tree, tree);
> > +extern tree finish_shorthand_constraint         (tree, tree, bool);
> >  extern tree finish_requires_expr                (location_t, tree, tree);
> >  extern tree finish_simple_requirement           (location_t, tree);
> >  extern tree finish_type_requirement             (location_t, tree);
> > diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc
> > index de9e960c683c..75d8c6badd66 100644
> > --- a/gcc/cp/mangle.cc
> > +++ b/gcc/cp/mangle.cc
> > @@ -1921,8 +1921,10 @@ write_template_param_decl (tree parm)
> >     write_string ("Tn");
> >  
> >     tree type = TREE_TYPE (decl);
> > +   /* TODO: We need to also mangle constrained auto*, auto&, etc, but
> > +      it's not clear how.  See finish_constrained_parameter.  */
> >     if (tree c = (is_auto (type)
> > -                 ? PLACEHOLDER_TYPE_CONSTRAINTS (type)
> > +                 ? TEMPLATE_PARM_CONSTRAINTS (parm)
> >                   : NULL_TREE))
> >       {
> >         if (AUTO_IS_DECLTYPE (type))
> > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> > index 4d988c27cb80..5ecaa1cb5e6d 100644
> > --- a/gcc/cp/parser.cc
> > +++ b/gcc/cp/parser.cc
> > @@ -20560,34 +20560,6 @@ cp_parser_check_constrained_type_parm (cp_parser 
> > *parser,
> >    return true;
> >  }
> >  
> > -/* Finish parsing/processing a template type parameter and checking
> > -   various restrictions. */
> > -
> > -static inline tree
> > -cp_parser_constrained_type_template_parm (cp_parser *parser,
> > -                                          tree id,
> > -                                          cp_parameter_declarator* 
> > parmdecl)
> > -{
> > -  if (cp_parser_check_constrained_type_parm (parser, parmdecl))
> > -    return finish_template_type_parm (class_type_node, id);
> > -  else
> > -    return error_mark_node;
> > -}
> > -
> > -/* Create a new non-type template parameter from the given PARM
> > -   declarator.  */
> > -
> > -static tree
> > -cp_parser_constrained_non_type_template_parm (bool *is_non_type,
> > -                                         cp_parameter_declarator *parm)
> > -{
> > -  *is_non_type = true;
> > -  cp_declarator *decl = parm->declarator;
> > -  cp_decl_specifier_seq *specs = &parm->decl_specifiers;
> > -  specs->type = TREE_TYPE (DECL_INITIAL (specs->type));
> > -  return grokdeclarator (decl, specs, TPARM, 0, NULL);
> > -}
> > -
> >  /* Build a constrained template parameter based on the PARMDECL
> >     declarator. The type of PARMDECL is the constrained type, which
> >     refers to the prototype template parameter that ultimately
> > @@ -20598,24 +20570,60 @@ finish_constrained_parameter (cp_parser *parser,
> >                                cp_parameter_declarator *parmdecl,
> >                                bool *is_non_type)
> >  {
> > -  tree decl = parmdecl->decl_specifiers.type;
> > +  tree constr = parmdecl->decl_specifiers.type;
> >    tree id = get_unqualified_id (parmdecl->declarator);
> >    tree def = parmdecl->default_argument;
> > -  tree proto = DECL_INITIAL (decl);
> >  
> >    /* Build the parameter. Return an error if the declarator was invalid. */
> > +  bool set_template_parm_constraints_p = true;
> >    tree parm;
> > -  if (TREE_CODE (proto) == TYPE_DECL)
> > -    parm = cp_parser_constrained_type_template_parm (parser, id, parmdecl);
> > +  if (is_constrained_auto (constr))
> > +    {
> > +      /* Constrained non-type parameter.  */
> > +      *is_non_type = true;
> > +      if (!parmdecl->declarator
> > +     || parmdecl->declarator->kind == cdk_id)
> > +   /* For a simple constrained auto NTTP, move its constraint from
> > +      PLACEHOLDER_TYPE_CONSTRAINTS to TEMPLATE_PARM_CONSTRAINTS to
> > +      eventually include them in the template's associated constraints.
> > +      finish_shorthand_constraint will convert the constraint to its
> > +      final form.  */
> > +   parmdecl->decl_specifiers.type = (AUTO_IS_DECLTYPE (constr)
> > +                                     ? make_decltype_auto ()
> > +                                     : make_auto ());
> > +      else
> > +   /* ??? For constrained auto*, auto& etc it's not clear how to represent
> > +      the type-constraint as an associated constraint (we need it in terms
> > +      of the pointed-to type).  So we keep it in TEMPLATE_PARM_CONSTRAINTS
> > +      and effectively treat it like a non-template constrained auto.  */
> > +   set_template_parm_constraints_p = false;
> > +      parm = grokdeclarator (parmdecl->declarator,
> > +                        &parmdecl->decl_specifiers,
> > +                        TPARM, /*initialized=*/0, /*attrlist=*/NULL);
> > +    }
> >    else
> > -    parm = cp_parser_constrained_non_type_template_parm (is_non_type, 
> > parmdecl);
> > +    {
> > +      /* Constrained type parameter.  */
> > +      gcc_checking_assert (CONSTRAINED_PARM_CONCEPT (constr));
> > +      if (cp_parser_check_constrained_type_parm (parser, parmdecl))
> > +   parm = finish_template_type_parm (class_type_node, id);
> > +      else
> > +   parm = error_mark_node;
> > +    }
> >    if (parm == error_mark_node)
> >      return error_mark_node;
> >  
> >    /* Finish the parameter decl and create a node attaching the
> >       default argument and constraint.  */
> >    parm = build_tree_list (def, parm);
> > -  TEMPLATE_PARM_CONSTRAINTS (parm) = decl;
> > +  if (set_template_parm_constraints_p)
> > +    {
> > +      if (*is_non_type)
> > +   TEMPLATE_PARM_CONSTRAINTS (parm)
> > +     = PLACEHOLDER_TYPE_CONSTRAINTS (constr);
> > +      else
> > +   TEMPLATE_PARM_CONSTRAINTS (parm) = constr;
> > +    }
> >  
> >    return parm;
> >  }
> > @@ -20812,7 +20820,9 @@ cp_parser_template_parameter (cp_parser* parser, 
> > bool *is_non_type,
> >      }
> >  
> >    /* The parameter may have been constrained type parameter.  */
> > -  if (declares_constrained_type_template_parameter (parameter_declarator))
> > +  tree type = parameter_declarator->decl_specifiers.type;
> > +  if (declares_constrained_type_template_parameter (parameter_declarator)
> > +      || (type && is_constrained_auto (type)))
> >      return finish_constrained_parameter (parser,
> >                                           parameter_declarator,
> >                                           is_non_type);
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index de101b180e38..d43ac7503b2d 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -184,7 +184,6 @@ static int template_decl_level (tree);
> >  static int check_cv_quals_for_unify (int, tree, tree);
> >  static int unify_pack_expansion (tree, tree, tree,
> >                              tree, unification_kind_t, bool, bool);
> > -static tree copy_template_args (tree);
> >  static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
> >  static void tsubst_each_template_parm_constraints (tree, tree, 
> > tsubst_flags_t);
> >  static tree tsubst_arg_types (tree, tree, tree, tsubst_flags_t, tree);
> > @@ -4747,7 +4746,7 @@ process_template_parm (tree list, location_t 
> > parm_loc, tree parm,
> >  
> >    tree decl = NULL_TREE;
> >    tree defval = TREE_PURPOSE (parm);
> > -  tree constr = TREE_TYPE (parm);
> > +  tree constr = TEMPLATE_PARM_CONSTRAINTS (parm);
> >  
> >    if (is_non_type)
> >      {
> > @@ -4845,7 +4844,7 @@ process_template_parm (tree list, location_t 
> > parm_loc, tree parm,
> >    /* Build requirements for the type/template parameter.
> >       This must be done after SET_DECL_TEMPLATE_PARM_P or
> >       process_template_parm could fail. */
> > -  tree reqs = finish_shorthand_constraint (parm, constr);
> > +  tree reqs = finish_shorthand_constraint (parm, constr, is_non_type);
> >  
> >    decl = pushdecl (decl);
> >    if (!is_non_type)
> > @@ -14395,7 +14394,7 @@ make_argument_pack (tree vec)
> >  /* Return an exact copy of template args T that can be modified
> >     independently.  */
> >  
> > -static tree
> > +tree
> >  copy_template_args (tree t)
> >  {
> >    if (t == error_mark_node)
> > @@ -30822,8 +30821,7 @@ make_constrained_placeholder_type (tree type, tree 
> > con, tree args)
> >    /* Our canonical type depends on the constraint.  */
> >    TYPE_CANONICAL (type) = canonical_type_parameter (type);
> >  
> > -  /* Attach the constraint to the type declaration. */
> > -  return TYPE_NAME (type);
> > +  return type;
> >  }
> >  
> >  /* Make a "constrained auto" type-specifier.  */
> > @@ -32638,6 +32636,11 @@ do_auto_deduction (tree type, tree init, tree 
> > auto_node,
> >      /* Constraints will be checked after deduction.  */;
> >    else if (tree constr = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS 
> > (auto_node)))
> >      {
> > +      if (context == adc_unify)
> > +   /* Simple constrained auto NTTPs should have gotten their constraints
> > +      moved to the template's associated constraints.  */
> > +   gcc_checking_assert (type != auto_node);
> > +
> >        if (processing_template_decl)
> >     {
> >       gcc_checking_assert (context == adc_variable_type
> > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C 
> > b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C
> > index 22f0ac5e26a1..edca8f7199bc 100644
> > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C
> > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-placeholder12.C
> > @@ -22,8 +22,8 @@ int main() {
> >    A<false>::g(X<0>{}); // { dg-error "no match|constraints" }
> >  
> >    bool v1 = A<true>::value<0>;
> > -  bool v2 = A<false>::value<0>;  // { dg-error "constraints" }
> > +  bool v2 = A<false>::value<0>;  // { dg-error "invalid variable template" 
> > }
> >  
> >    A<true>::D<0> d1;
> > -  A<false>::D<0> d2; // { dg-error "constraints" }
> > +  A<false>::D<0> d2; // { dg-error "constraint failure" }
> >  }
> > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C 
> > b/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C
> > index d662552614e5..355f195ac0ad 100644
> > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C
> > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr97093.C
> > @@ -29,4 +29,4 @@ struct pc
> >  };
> >  
> >  constexpr auto cc = pc {};
> > -constexpr auto mmcc = m <cc> {}; // { dg-error "not satisfied" }
> > +constexpr auto mmcc = m <cc> {}; // { dg-error "constraint failure" }
> > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm12.C 
> > b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm12.C
> > new file mode 100644
> > index 000000000000..713b1d050825
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm12.C
> > @@ -0,0 +1,31 @@
> > +// { dg-do compile { target c++20 } }
> > +// Verify partial ordering with respect to associated constraints
> > +// works in the presence of constrained NTTPs.
> > +
> > +template<class T> concept C = true;
> > +
> > +template<class T> concept D = C<T> && true;
> > +
> > +template<class T> concept E = true;
> > +
> > +template<C auto V> void f() = delete;
> > +template<D auto V> void f(); // more constrained
> > +
> > +template<C auto V> void g();
> > +template<C auto V> void g(); // redeclaration
> > +
> > +template<C auto V> void h();
> > +template<E auto V> void h(); // neither more nor less constrained
> > +
> > +template<C auto V> struct A;
> > +template<D auto V> struct A<V> { }; // more constrained
> > +
> > +template<D auto V> struct B;
> > +template<C auto V> struct B<V> { }; // { dg-error "not more constrained" }
> > +
> > +int main() {
> > +  f<0>();
> > +  g<0>();
> > +  h<0>(); // { dg-error "ambiguous" }
> > +  A<0> a;
> > +}
> > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C 
> > b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C
> > index 3bb2f576a873..a9b15dabc0cf 100644
> > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C
> > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm2.C
> > @@ -12,4 +12,4 @@ template<Int T = char> struct S1 { };
> >  template<Int auto X = false> struct S2 { };
> >  
> >  S1<> s1; // { dg-error "constraint failure" }
> > -S2<> s2; // { dg-error "placeholder constraints not satisfied" }
> > +S2<> s2; // { dg-error "constraint failure" }
> > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C 
> > b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C
> > index c7d9964f7388..04c2e1c70ba6 100644
> > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C
> > +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-template-parm6.C
> > @@ -40,5 +40,5 @@ template<Int... Ts> struct S3 { }; // requires (C<Ts> && 
> > ...)
> >  S3<int, int, char> x0; // { dg-error "template constraint failure" }
> >  
> >  template<Int auto... Xs> struct S4 { }; // requires (C<X> && ...) with 
> > each X deduced
> > -S4<0, 1, 2, 'a'> x1; // { dg-error "placeholder constraints not satisfied" 
> > }
> > +S4<0, 1, 2, 'a'> x1; // { dg-error "template constraint failure" }
> >  
> > -- 
> > 2.53.0.rc1.65.gea24e2c554
> > 
> > 
> 

Reply via email to