Re: [PATCH v1] c++: Hash placeholder constraint in ctp_hasher

2024-07-17 Thread Seyed Sajad Kahani
On Tue, 16 Jul 2024 at 17:05, Jason Merrill  wrote:
> The change looks good, just a couple of whitespace tweaks needed.  But
> what happened to the testcase?

I was unable to design any testcase that differs by applying this
patch, due to the proper handling of hash collisions
(hash-table.h:1059).

> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -4525,7 +4525,12 @@ struct ctp_hasher : ggc_ptr_hash
> >   val = iterative_hash_object (TEMPLATE_TYPE_LEVEL (t), val);
> >   val = iterative_hash_object (TEMPLATE_TYPE_IDX (t), val);
> >   if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
> > -  val = iterative_hash_template_arg (CLASS_PLACEHOLDER_TEMPLATE (t), 
> > val);
> > +  {
> > + val
>
> Extra space at end of line.
>
> > +   = iterative_hash_template_arg (CLASS_PLACEHOLDER_TEMPLATE (t), val);
> > + if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
> > +   val = iterative_hash_placeholder_constraint(c, val);
>
> Missing space before paren.

My apologies. Thank you for pointing those out.


Re: [PATCH v1] c++: Hash placeholder constraint in ctp_hasher

2024-07-16 Thread Jason Merrill

On 7/12/24 4:42 PM, Seyed Sajad Kahani wrote:

This patch addresses a difference between the hash function and the equality
function for canonical types of template parameters (ctp_hasher). The equality
function uses comptypes (typeck.cc) (with COMPARE_STRUCTURAL) and checks
constraint equality for two auto nodes (typeck.cc:1586), while the hash
function ignores it (pt.cc:4528). This leads to hash collisions that can be
avoided by using `hash_placeholder_constraint` (constraint.cc:1150).


The change looks good, just a couple of whitespace tweaks needed.  But 
what happened to the testcase?



--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4525,7 +4525,12 @@ struct ctp_hasher : ggc_ptr_hash
  val = iterative_hash_object (TEMPLATE_TYPE_LEVEL (t), val);
  val = iterative_hash_object (TEMPLATE_TYPE_IDX (t), val);
  if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-  val = iterative_hash_template_arg (CLASS_PLACEHOLDER_TEMPLATE (t), val);
+  {
+   val


Extra space at end of line.


+ = iterative_hash_template_arg (CLASS_PLACEHOLDER_TEMPLATE (t), val);
+   if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
+ val = iterative_hash_placeholder_constraint(c, val);


Missing space before paren.

Jason



Re: [PATCH v1] c++: Hash placeholder constraint in ctp_hasher

2024-07-12 Thread Seyed Sajad Kahani
I am sorry for the inconvenience, a fixed version was sent just now.


[PATCH v1] c++: Hash placeholder constraint in ctp_hasher

2024-07-12 Thread Seyed Sajad Kahani
This patch addresses a difference between the hash function and the equality
function for canonical types of template parameters (ctp_hasher). The equality
function uses comptypes (typeck.cc) (with COMPARE_STRUCTURAL) and checks
constraint equality for two auto nodes (typeck.cc:1586), while the hash
function ignores it (pt.cc:4528). This leads to hash collisions that can be
avoided by using `hash_placeholder_constraint` (constraint.cc:1150).

* constraint.cc (hash_placeholder_constraint): Rename to
iterative_hash_placeholder_constraint.
(iterative_hash_placeholder_constraint): Rename from
hash_placeholder_constraint and add the initial val argument.
* cp-tree.h (hash_placeholder_constraint): Rename to
iterative_hash_placeholder_constraint.
(iterative_hash_placeholder_constraint): Renamed from
hash_placeholder_constraint and add the initial val argument.
* pt.cc (struct ctp_hasher): Updated to use
iterative_hash_placeholder_constraint in the case of a valid placeholder
constraint.
(auto_hash::hash): Reflect the renaming of hash_placeholder_constraint 
to
iterative_hash_placeholder_constraint.
---
 gcc/cp/constraint.cc | 4 ++--
 gcc/cp/cp-tree.h | 2 +-
 gcc/cp/pt.cc | 9 +++--
 3 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index ebf4255e5..78aacb77a 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1971,13 +1971,13 @@ equivalent_placeholder_constraints (tree c1, tree c2)
 /* Return a hash value for the placeholder ATOMIC_CONSTR C.  */
 
 hashval_t
-hash_placeholder_constraint (tree c)
+iterative_hash_placeholder_constraint (tree c, hashval_t val)
 {
   tree t, a;
   placeholder_extract_concept_and_args (c, t, a);
 
   /* Like hash_tmpl_and_args, but skip the first argument.  */
-  hashval_t val = iterative_hash_object (DECL_UID (t), 0);
+  val = iterative_hash_object (DECL_UID (t), val);
 
   for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
 val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 4bb3e9c49..294e88f75 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -8588,7 +8588,7 @@ extern tree_pair finish_type_constraints  (tree, tree, 
tsubst_flags_t);
 extern tree build_constrained_parameter (tree, tree, tree = NULL_TREE);
 extern void placeholder_extract_concept_and_args (tree, tree&, tree&);
 extern bool equivalent_placeholder_constraints  (tree, tree);
-extern hashval_t hash_placeholder_constraint   (tree);
+extern hashval_t iterative_hash_placeholder_constraint (tree, hashval_t);
 extern bool deduce_constrained_parameter(tree, tree&, tree&);
 extern tree resolve_constraint_check(tree);
 extern tree check_function_concept  (tree);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index d1316483e..9a80c44a5 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4525,7 +4525,12 @@ struct ctp_hasher : ggc_ptr_hash
 val = iterative_hash_object (TEMPLATE_TYPE_LEVEL (t), val);
 val = iterative_hash_object (TEMPLATE_TYPE_IDX (t), val);
 if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
-  val = iterative_hash_template_arg (CLASS_PLACEHOLDER_TEMPLATE (t), val);
+  {
+   val 
+ = iterative_hash_template_arg (CLASS_PLACEHOLDER_TEMPLATE (t), val);
+   if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
+ val = iterative_hash_placeholder_constraint(c, val);
+  }
 if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
   val = iterative_hash_template_arg (TYPE_TI_ARGS (t), val);
 --comparing_specializations;
@@ -29605,7 +29610,7 @@ auto_hash::hash (tree t)
   if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
 /* Matching constrained-type-specifiers denote the same template
parameter, so hash the constraint.  */
-return hash_placeholder_constraint (c);
+return iterative_hash_placeholder_constraint (c, 0);
   else
 /* But unconstrained autos are all separate, so just hash the pointer.  */
 return iterative_hash_object (t, 0);
-- 
2.45.2



Re: [PATCH v1] c++: Hash placeholder constraint in ctp_hasher

2024-07-12 Thread Andrew Pinski
oint, it becomes difficult to find partially
> > specialised args, as they are erased in the process. I propose modifying 
> > tsubst
> > to eagerly substitute the constraint args of an auto node.
> >
> > By making this change, we would not need to provide outer_targs for
> > do_auto_deduction in cases where tsubst has been called for the type, which
> > covers most scenarios. However, we still need outer_targs for cases like:
> >
> > template  auto V>
> > struct S { };
> >
> > Hence, outer_targs cannot be completely removed but will be set to 
> > TREE_NULL in
> > all calls except the one in convert_template_argument (pt.cc:8788).
> > Additionally, the tmpl argument of do_auto_deduction, which helps to provide
> > outer args in the scope, will no longer be necessary and can be safely
> > removed.
> >
> > Also, the trimming hack proposed in
> > https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654724.html to address
> > C++/PR114915 is no longer needed. We will add an assertion to ensure that 
> > the
> > missing levels do not become negative.
> >
> > Substituting constraint arguments earlier will slightly alter error messages
> > (see testsuite/g++.dg/cpp2a/concepts-placeholder3.C as an example).
> >
> > To summarise, I have made the following changes:
> > - Modified tsubst to substitute the constraint args.
> > - Fixed shallow checks for using the cache from TEMPLATE_TYPE_DESCENDANTS
> > (pt.cc:16513).
> > - Substituted the constraint args and the auto node itself, while retaining 
> > all
> > other parameters as is (pt.cc:16533).
> > - Removed now unnecessary code that attempted to find outer scope template 
> > info
> > and args in various locations.
> > - Updated the missing levels hack (pt.cc:31320) to work with the substituted
> > constraints.
> > - Used level instead of orig_level to find the missing levels.
> > - Added an assertion for future safety.
> >
> > Details of these changes can be found in the patch "[PATCH v1] c++: Eagerly
> > substitute auto constraint args in tsubst [PR115030]" that will be replied 
> > to
> > this thread.
> >
> > This patch, in my opinion, improves code quality by removing an argument 
> > from
> > do_auto_deduction and eliminating the out-of-scope task of finding 
> > outer_targs
> > within do_auto_deduction. It simplifies the usage of do_auto_deduction and
> > resolves C++/PR115030 without complex calculations for specialised args. It
> > also enhances the consistency of tsubst behaviour by not leaving constraints
> > un-substituted. However, these changes make args in constraints_satisfied_p
> > (being called from do_auto_deduction) a bit misleading, as it will not carry
> > the actual args of the constraint and can even be an empty vec.
> >
> > I have added a testsuite for C++/PR115030, and as far as I have tested (only
> > c++ dg.exp on x86_64-linux), there are no regressions.
> >
> > Extra:
> > While doing this, I also realised that the hash function in ctp_hasher (for
> > canonical type of template parameters) slightly differs from its equality
> > function. Specifically, the equality function uses comptypes (typeck.cc) 
> > (with
> > COMPARE_STRUCTURAL) and compares placeholder constraints (typeck.cc:1586),
> > while the hash function ignores them (pt.cc:4528). As a result, we can have 
> > two
> > types with equal hashes that are unequal. For example, assuming:
> >
> > template 
> > concept C1 = ...
> >
> > template 
> > concept C2 = ...
> >
> >
> > "C1 auto" and "C2 auto" have the same hash value but are unequal. This
> > issue does not cause any error (it is a hash collision and it is handled), 
> > but
> > it can be avoided by using hash_placeholder_constraint (constraint.cc:1150).
> >
> > Therefore, I have made the following changes:
> > - Fixed the hash function to calculate the hash of the constraint 
> > (pt.cc:4528).
> > - Slightly modified the existing hash_placeholder_constraint
> > (constraint.cc:1150) to accept the initial hash value as an argument.
> >
> > Details of these changes can be found in the patch "[PATCH v1] c++: Hash
> > placeholder constraint in ctp_hasher" that will be replied to this email.
> >
> > Thanks. I really appreciate your comments and feedback on these proposed
> > changes.


Re: [PATCH v1] c++: Hash placeholder constraint in ctp_hasher

2024-07-12 Thread Patrick Palka
tion (pt.cc), where we attempt to find the substituted args of 
> > the
> > enclosing scope. At that point, it becomes difficult to find partially
> > specialised args, as they are erased in the process. I propose modifying 
> > tsubst
> > to eagerly substitute the constraint args of an auto node.
> >
> > By making this change, we would not need to provide outer_targs for
> > do_auto_deduction in cases where tsubst has been called for the type, which
> > covers most scenarios. However, we still need outer_targs for cases like:
> >
> > template  auto V>
> > struct S { };
> >
> > Hence, outer_targs cannot be completely removed but will be set to 
> > TREE_NULL in
> > all calls except the one in convert_template_argument (pt.cc:8788).
> > Additionally, the tmpl argument of do_auto_deduction, which helps to provide
> > outer args in the scope, will no longer be necessary and can be safely
> > removed.
> >
> > Also, the trimming hack proposed in
> > https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654724.html to address
> > C++/PR114915 is no longer needed. We will add an assertion to ensure that 
> > the
> > missing levels do not become negative.
> >
> > Substituting constraint arguments earlier will slightly alter error messages
> > (see testsuite/g++.dg/cpp2a/concepts-placeholder3.C as an example).
> >
> > To summarise, I have made the following changes:
> > - Modified tsubst to substitute the constraint args.
> > - Fixed shallow checks for using the cache from TEMPLATE_TYPE_DESCENDANTS
> > (pt.cc:16513).
> > - Substituted the constraint args and the auto node itself, while retaining 
> > all
> > other parameters as is (pt.cc:16533).
> > - Removed now unnecessary code that attempted to find outer scope template 
> > info
> > and args in various locations.
> > - Updated the missing levels hack (pt.cc:31320) to work with the substituted
> > constraints.
> > - Used level instead of orig_level to find the missing levels.
> > - Added an assertion for future safety.
> >
> > Details of these changes can be found in the patch "[PATCH v1] c++: Eagerly
> > substitute auto constraint args in tsubst [PR115030]" that will be replied 
> > to
> > this thread.
> >
> > This patch, in my opinion, improves code quality by removing an argument 
> > from
> > do_auto_deduction and eliminating the out-of-scope task of finding 
> > outer_targs
> > within do_auto_deduction. It simplifies the usage of do_auto_deduction and
> > resolves C++/PR115030 without complex calculations for specialised args. It
> > also enhances the consistency of tsubst behaviour by not leaving constraints
> > un-substituted. However, these changes make args in constraints_satisfied_p
> > (being called from do_auto_deduction) a bit misleading, as it will not carry
> > the actual args of the constraint and can even be an empty vec.
> >
> > I have added a testsuite for C++/PR115030, and as far as I have tested (only
> > c++ dg.exp on x86_64-linux), there are no regressions.
> >
> > Extra:
> > While doing this, I also realised that the hash function in ctp_hasher (for
> > canonical type of template parameters) slightly differs from its equality
> > function. Specifically, the equality function uses comptypes (typeck.cc) 
> > (with
> > COMPARE_STRUCTURAL) and compares placeholder constraints (typeck.cc:1586),
> > while the hash function ignores them (pt.cc:4528). As a result, we can have 
> > two
> > types with equal hashes that are unequal. For example, assuming:
> >
> > template 
> > concept C1 = ...
> >
> > template 
> > concept C2 = ...
> >
> >
> > "C1 auto" and "C2 auto" have the same hash value but are unequal. This
> > issue does not cause any error (it is a hash collision and it is handled), 
> > but
> > it can be avoided by using hash_placeholder_constraint (constraint.cc:1150).
> >
> > Therefore, I have made the following changes:
> > - Fixed the hash function to calculate the hash of the constraint 
> > (pt.cc:4528).
> > - Slightly modified the existing hash_placeholder_constraint
> > (constraint.cc:1150) to accept the initial hash value as an argument.
> >
> > Details of these changes can be found in the patch "[PATCH v1] c++: Hash
> > placeholder constraint in ctp_hasher" that will be replied to this email.
> >
> > Thanks. I really appreciate your comments and feedback on these proposed
> > changes.
> 
> 



[PATCH v1] c++: Hash placeholder constraint in ctp_hasher

2024-07-09 Thread Seyed Sajad Kahani
ally, the tmpl argument of do_auto_deduction, which helps to provide
> outer args in the scope, will no longer be necessary and can be safely
> removed.
>
> Also, the trimming hack proposed in
> https://gcc.gnu.org/pipermail/gcc-patches/2024-June/654724.html to address
> C++/PR114915 is no longer needed. We will add an assertion to ensure that the
> missing levels do not become negative.
>
> Substituting constraint arguments earlier will slightly alter error messages
> (see testsuite/g++.dg/cpp2a/concepts-placeholder3.C as an example).
>
> To summarise, I have made the following changes:
> - Modified tsubst to substitute the constraint args.
> - Fixed shallow checks for using the cache from TEMPLATE_TYPE_DESCENDANTS
> (pt.cc:16513).
> - Substituted the constraint args and the auto node itself, while retaining 
> all
> other parameters as is (pt.cc:16533).
> - Removed now unnecessary code that attempted to find outer scope template 
> info
> and args in various locations.
> - Updated the missing levels hack (pt.cc:31320) to work with the substituted
> constraints.
> - Used level instead of orig_level to find the missing levels.
> - Added an assertion for future safety.
>
> Details of these changes can be found in the patch "[PATCH v1] c++: Eagerly
> substitute auto constraint args in tsubst [PR115030]" that will be replied to
> this thread.
>
> This patch, in my opinion, improves code quality by removing an argument from
> do_auto_deduction and eliminating the out-of-scope task of finding outer_targs
> within do_auto_deduction. It simplifies the usage of do_auto_deduction and
> resolves C++/PR115030 without complex calculations for specialised args. It
> also enhances the consistency of tsubst behaviour by not leaving constraints
> un-substituted. However, these changes make args in constraints_satisfied_p
> (being called from do_auto_deduction) a bit misleading, as it will not carry
> the actual args of the constraint and can even be an empty vec.
>
> I have added a testsuite for C++/PR115030, and as far as I have tested (only
> c++ dg.exp on x86_64-linux), there are no regressions.
>
> Extra:
> While doing this, I also realised that the hash function in ctp_hasher (for
> canonical type of template parameters) slightly differs from its equality
> function. Specifically, the equality function uses comptypes (typeck.cc) (with
> COMPARE_STRUCTURAL) and compares placeholder constraints (typeck.cc:1586),
> while the hash function ignores them (pt.cc:4528). As a result, we can have 
> two
> types with equal hashes that are unequal. For example, assuming:
>
> template 
> concept C1 = ...
>
> template 
> concept C2 = ...
>
>
> "C1 auto" and "C2 auto" have the same hash value but are unequal. This
> issue does not cause any error (it is a hash collision and it is handled), but
> it can be avoided by using hash_placeholder_constraint (constraint.cc:1150).
>
> Therefore, I have made the following changes:
> - Fixed the hash function to calculate the hash of the constraint 
> (pt.cc:4528).
> - Slightly modified the existing hash_placeholder_constraint
> (constraint.cc:1150) to accept the initial hash value as an argument.
>
> Details of these changes can be found in the patch "[PATCH v1] c++: Hash
> placeholder constraint in ctp_hasher" that will be replied to this email.
>
> Thanks. I really appreciate your comments and feedback on these proposed
> changes.