Re: [PATCH 2/2] c++: partial ordering and dep alias tmpl specs [PR90679]

2023-12-18 Thread Jason Merrill

On 12/15/23 14:07, Patrick Palka wrote:

On Thu, 1 Jun 2023, Patrick Palka wrote:


During partial ordering, we want to look through dependent alias
template specializations within template arguments and otherwise
treat them as opaque in other contexts (see e.g. r7-7116-g0c942f3edab108
and r11-7011-g6e0a231a4aa240).  To that end template_args_equal was
given a partial_order flag that controls this behavior.  This flag
does the right thing when a dependent alias template specialization
appears as template argument of the partial specialization, e.g. in

   template using first_t = T;
   template struct traits;
   template struct traits> { }; // #1
   template struct traits> { }; // #2

we correctly consider #2 to be more specialized than #1.  But if
the alias specialization appears as a template argument of another
class template specialization, e.g. in

   template struct traits>> { }; // #1
   template struct traits>> { }; // #2

then we incorrectly consider #1 and #2 to be unordered.  This is because

   1. we don't propagate the flag to recursive template_args_equal calls
   2. we don't use structural equality for class template specializations
  written in terms of dependent alias template specializations

This patch fixes the first issue by turning the partial_order flag into
a global.  This patch fixes the second issue by making us propagate
structural equality appropriately when building a class template
specialization.  In passing this patch also improves hashing of
specializations that use structural equality.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

PR c++/90679

gcc/cp/ChangeLog:

* cp-tree.h (comp_template_args): Remove partial_order
parameter.
(template_args_equal): Likewise.
* pt.cc (iterative_hash_template_arg) : Hash
the template and arguments for specializations that use
structural equality.
(comparing_for_partial_ordering): New flag.
(template_args_equal): Remove partial order parameter and
use comparing_for_partial_ordering instead.
(comp_template_args): Likewise.
(comp_template_args_porder): Set comparing_for_partial_ordering
instead.  Make static.
(any_template_arguments_need_structural_equality_p): Return true
for an argument that's a dependent alias template specialization
or a class template specialization that itself needs structural
equality.
* tree.cc (cp_tree_equal) : Adjust call to
comp_template_args.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alias-decl-75a.C: New test.
* g++.dg/cpp0x/alias-decl-75b.C: New test.


Ping.  Here's the rebased patch:

-- >8 --

Subject: [PATCH 2/2] c++: partial ordering and dep alias tmpl specs [PR90679]

During partial ordering, we want to look through dependent alias
template specializations within template arguments and otherwise
treat them as opaque in other contexts (see e.g. r7-7116-g0c942f3edab108
and r11-7011-g6e0a231a4aa240).  To that end template_args_equal was
given a partial_order flag that controls this behavior.  This flag
does the right thing when a dependent alias template specialization
appears as template argument of the partial specialization, e.g. in

   template using first_t = T;
   template struct traits;
   template struct traits> { }; // #1
   template struct traits> { }; // #2

we correctly consider #2 to be more specialized than #1.  But if
the alias specialization appears as a template argument of another
class template specialization, e.g. in

   template struct traits>> { }; // #1
   template struct traits>> { }; // #2

then we incorrectly consider #1 and #2 to be unordered.  This is because

   1. we don't propagate the flag to recursive template_args_equal calls
   2. we don't use structural equality for class template specializations
  written in terms of dependent alias template specializations

This patch fixes the first issue by turning the partial_order flag into
a global.  This patch fixes the second issue by making us propagate
structural equality appropriately when building a class template
specialization.  In passing this patch also improves hashing of
specializations that use structural equality.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

PR c++/90679

gcc/cp/ChangeLog:

* cp-tree.h (comp_template_args): Remove partial_order
parameter.
(template_args_equal): Likewise.
* pt.cc (iterative_hash_template_arg) : Hash
the template and arguments for specializations that use
structural equality.
(comparing_for_partial_ordering): New flag.
(template_args_equal): Remove partial order parameter and
use comparing_for_partial_ordering instead.
(comp_template_args): Likewise.
(comp_template_args_porder): Set comparing_for_partial

Re: [PATCH 2/2] c++: partial ordering and dep alias tmpl specs [PR90679]

2023-12-15 Thread Patrick Palka
On Thu, 1 Jun 2023, Patrick Palka wrote:

> During partial ordering, we want to look through dependent alias
> template specializations within template arguments and otherwise
> treat them as opaque in other contexts (see e.g. r7-7116-g0c942f3edab108
> and r11-7011-g6e0a231a4aa240).  To that end template_args_equal was
> given a partial_order flag that controls this behavior.  This flag
> does the right thing when a dependent alias template specialization
> appears as template argument of the partial specialization, e.g. in
> 
>   template using first_t = T;
>   template struct traits;
>   template struct traits> { }; // #1
>   template struct traits> { }; // #2
> 
> we correctly consider #2 to be more specialized than #1.  But if
> the alias specialization appears as a template argument of another
> class template specialization, e.g. in
> 
>   template struct traits>> { }; // #1
>   template struct traits>> { }; // #2
> 
> then we incorrectly consider #1 and #2 to be unordered.  This is because
> 
>   1. we don't propagate the flag to recursive template_args_equal calls
>   2. we don't use structural equality for class template specializations
>  written in terms of dependent alias template specializations
> 
> This patch fixes the first issue by turning the partial_order flag into
> a global.  This patch fixes the second issue by making us propagate
> structural equality appropriately when building a class template
> specialization.  In passing this patch also improves hashing of
> specializations that use structural equality.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?
> 
>   PR c++/90679
> 
> gcc/cp/ChangeLog:
> 
>   * cp-tree.h (comp_template_args): Remove partial_order
>   parameter.
>   (template_args_equal): Likewise.
>   * pt.cc (iterative_hash_template_arg) : Hash
>   the template and arguments for specializations that use
>   structural equality.
>   (comparing_for_partial_ordering): New flag.
>   (template_args_equal): Remove partial order parameter and
>   use comparing_for_partial_ordering instead.
>   (comp_template_args): Likewise.
>   (comp_template_args_porder): Set comparing_for_partial_ordering
>   instead.  Make static.
>   (any_template_arguments_need_structural_equality_p): Return true
>   for an argument that's a dependent alias template specialization
>   or a class template specialization that itself needs structural
>   equality.
>   * tree.cc (cp_tree_equal) : Adjust call to
>   comp_template_args.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp0x/alias-decl-75a.C: New test.
>   * g++.dg/cpp0x/alias-decl-75b.C: New test.

Ping.  Here's the rebased patch:

-- >8 --

Subject: [PATCH 2/2] c++: partial ordering and dep alias tmpl specs [PR90679]

During partial ordering, we want to look through dependent alias
template specializations within template arguments and otherwise
treat them as opaque in other contexts (see e.g. r7-7116-g0c942f3edab108
and r11-7011-g6e0a231a4aa240).  To that end template_args_equal was
given a partial_order flag that controls this behavior.  This flag
does the right thing when a dependent alias template specialization
appears as template argument of the partial specialization, e.g. in

  template using first_t = T;
  template struct traits;
  template struct traits> { }; // #1
  template struct traits> { }; // #2

we correctly consider #2 to be more specialized than #1.  But if
the alias specialization appears as a template argument of another
class template specialization, e.g. in

  template struct traits>> { }; // #1
  template struct traits>> { }; // #2

then we incorrectly consider #1 and #2 to be unordered.  This is because

  1. we don't propagate the flag to recursive template_args_equal calls
  2. we don't use structural equality for class template specializations
 written in terms of dependent alias template specializations

This patch fixes the first issue by turning the partial_order flag into
a global.  This patch fixes the second issue by making us propagate
structural equality appropriately when building a class template
specialization.  In passing this patch also improves hashing of
specializations that use structural equality.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

PR c++/90679

gcc/cp/ChangeLog:

* cp-tree.h (comp_template_args): Remove partial_order
parameter.
(template_args_equal): Likewise.
* pt.cc (iterative_hash_template_arg) : Hash
the template and arguments for specializations that use
structural equality.
(comparing_for_partial_ordering): New flag.
(template_ar

Re: [PATCH 2/2] c++: partial ordering and dep alias tmpl specs [PR90679]

2023-09-11 Thread Patrick Palka via Gcc-patches
On Thu, 1 Jun 2023, Patrick Palka wrote:

> During partial ordering, we want to look through dependent alias
> template specializations within template arguments and otherwise
> treat them as opaque in other contexts (see e.g. r7-7116-g0c942f3edab108
> and r11-7011-g6e0a231a4aa240).  To that end template_args_equal was
> given a partial_order flag that controls this behavior.  This flag
> does the right thing when a dependent alias template specialization
> appears as template argument of the partial specialization, e.g. in
> 
>   template using first_t = T;
>   template struct traits;
>   template struct traits> { }; // #1
>   template struct traits> { }; // #2
> 
> we correctly consider #2 to be more specialized than #1.  But if
> the alias specialization appears as a template argument of another
> class template specialization, e.g. in
> 
>   template struct traits>> { }; // #1
>   template struct traits>> { }; // #2
> 
> then we incorrectly consider #1 and #2 to be unordered.  This is because
> 
>   1. we don't propagate the flag to recursive template_args_equal calls
>   2. we don't use structural equality for class template specializations
>  written in terms of dependent alias template specializations
> 
> This patch fixes the first issue by turning the partial_order flag into
> a global.  This patch fixes the second issue by making us propagate
> structural equality appropriately when building a class template
> specialization.  In passing this patch also improves hashing of
> specializations that use structural equality.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?

Ping.

> 
>   PR c++/90679
> 
> gcc/cp/ChangeLog:
> 
>   * cp-tree.h (comp_template_args): Remove partial_order
>   parameter.
>   (template_args_equal): Likewise.
>   * pt.cc (iterative_hash_template_arg) : Hash
>   the template and arguments for specializations that use
>   structural equality.
>   (comparing_for_partial_ordering): New flag.
>   (template_args_equal): Remove partial order parameter and
>   use comparing_for_partial_ordering instead.
>   (comp_template_args): Likewise.
>   (comp_template_args_porder): Set comparing_for_partial_ordering
>   instead.  Make static.
>   (any_template_arguments_need_structural_equality_p): Return true
>   for an argument that's a dependent alias template specialization
>   or a class template specialization that itself needs structural
>   equality.
>   * tree.cc (cp_tree_equal) : Adjust call to
>   comp_template_args.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp0x/alias-decl-75a.C: New test.
>   * g++.dg/cpp0x/alias-decl-75b.C: New test.
> ---
>  gcc/cp/cp-tree.h|  4 +--
>  gcc/cp/pt.cc| 40 +
>  gcc/cp/tree.cc  |  2 +-
>  gcc/testsuite/g++.dg/cpp0x/alias-decl-75a.C | 26 ++
>  gcc/testsuite/g++.dg/cpp0x/alias-decl-75b.C | 26 ++
>  5 files changed, 88 insertions(+), 10 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-75a.C
>  create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-75b.C
> 
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 5330d1e1f62..f08e5630a5c 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -7381,8 +7381,8 @@ extern int template_class_depth (tree);
>  extern int is_specialization_of  (tree, tree);
>  extern bool is_specialization_of_friend  (tree, tree);
>  extern bool comp_template_args   (tree, tree, tree * = 
> NULL,
> -  tree * = NULL, bool = false);
> -extern int template_args_equal  (tree, tree, bool = false);
> +  tree * = NULL);
> +extern int template_args_equal  (tree, tree);
>  extern tree maybe_process_partial_specialization (tree);
>  extern tree most_specialized_instantiation   (tree);
>  extern tree most_specialized_partial_spec   (tree, tsubst_flags_t);
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index 1b28195e10d..1a32f10b22b 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -1913,6 +1913,11 @@ iterative_hash_template_arg (tree arg, hashval_t val)
>   default:
> if (tree canonical = TYPE_CANONICAL (arg))
>   val = iterative_hash_object (TYPE_HASH (canonical), val);
> +   else if (tree ti = TYPE_TEMPLATE_INFO (arg))
> + {
> +   val = iterative_hash_template_arg (TI_TEMPLATE (ti), val);
> +   val = iterative_hash_template_arg (TI_ARGS (ti), val);
> + }
> break;
>   }
>  
> @@ -9296,6 +9301,12 @@ coerce_template_parms (tree parms,
>return return_full_args ? new_args : new_inner_args;
>  }
>  
> +/* Whether we are comparing template arguments during partial ordering
> +   (and 

[PATCH 2/2] c++: partial ordering and dep alias tmpl specs [PR90679]

2023-06-01 Thread Patrick Palka via Gcc-patches
During partial ordering, we want to look through dependent alias
template specializations within template arguments and otherwise
treat them as opaque in other contexts (see e.g. r7-7116-g0c942f3edab108
and r11-7011-g6e0a231a4aa240).  To that end template_args_equal was
given a partial_order flag that controls this behavior.  This flag
does the right thing when a dependent alias template specialization
appears as template argument of the partial specialization, e.g. in

  template using first_t = T;
  template struct traits;
  template struct traits> { }; // #1
  template struct traits> { }; // #2

we correctly consider #2 to be more specialized than #1.  But if
the alias specialization appears as a template argument of another
class template specialization, e.g. in

  template struct traits>> { }; // #1
  template struct traits>> { }; // #2

then we incorrectly consider #1 and #2 to be unordered.  This is because

  1. we don't propagate the flag to recursive template_args_equal calls
  2. we don't use structural equality for class template specializations
 written in terms of dependent alias template specializations

This patch fixes the first issue by turning the partial_order flag into
a global.  This patch fixes the second issue by making us propagate
structural equality appropriately when building a class template
specialization.  In passing this patch also improves hashing of
specializations that use structural equality.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

PR c++/90679

gcc/cp/ChangeLog:

* cp-tree.h (comp_template_args): Remove partial_order
parameter.
(template_args_equal): Likewise.
* pt.cc (iterative_hash_template_arg) : Hash
the template and arguments for specializations that use
structural equality.
(comparing_for_partial_ordering): New flag.
(template_args_equal): Remove partial order parameter and
use comparing_for_partial_ordering instead.
(comp_template_args): Likewise.
(comp_template_args_porder): Set comparing_for_partial_ordering
instead.  Make static.
(any_template_arguments_need_structural_equality_p): Return true
for an argument that's a dependent alias template specialization
or a class template specialization that itself needs structural
equality.
* tree.cc (cp_tree_equal) : Adjust call to
comp_template_args.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/alias-decl-75a.C: New test.
* g++.dg/cpp0x/alias-decl-75b.C: New test.
---
 gcc/cp/cp-tree.h|  4 +--
 gcc/cp/pt.cc| 40 +
 gcc/cp/tree.cc  |  2 +-
 gcc/testsuite/g++.dg/cpp0x/alias-decl-75a.C | 26 ++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-75b.C | 26 ++
 5 files changed, 88 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-75a.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-75b.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 5330d1e1f62..f08e5630a5c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7381,8 +7381,8 @@ extern int template_class_depth   (tree);
 extern int is_specialization_of(tree, tree);
 extern bool is_specialization_of_friend(tree, tree);
 extern bool comp_template_args (tree, tree, tree * = NULL,
-tree * = NULL, bool = false);
-extern int template_args_equal  (tree, tree, bool = false);
+tree * = NULL);
+extern int template_args_equal  (tree, tree);
 extern tree maybe_process_partial_specialization (tree);
 extern tree most_specialized_instantiation (tree);
 extern tree most_specialized_partial_spec   (tree, tsubst_flags_t);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 1b28195e10d..1a32f10b22b 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -1913,6 +1913,11 @@ iterative_hash_template_arg (tree arg, hashval_t val)
default:
  if (tree canonical = TYPE_CANONICAL (arg))
val = iterative_hash_object (TYPE_HASH (canonical), val);
+ else if (tree ti = TYPE_TEMPLATE_INFO (arg))
+   {
+ val = iterative_hash_template_arg (TI_TEMPLATE (ti), val);
+ val = iterative_hash_template_arg (TI_ARGS (ti), val);
+   }
  break;
}
 
@@ -9296,6 +9301,12 @@ coerce_template_parms (tree parms,
   return return_full_args ? new_args : new_inner_args;
 }
 
+/* Whether we are comparing template arguments during partial ordering
+   (and therefore want the comparison to look through dependent alias
+   template specializations).  */
+
+static int comparing_for_partial_ordering;
+
 /* Returns true if T is a wrapper to make a C++20 template