mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
c++: Hash placeholder constraint in ctp_hasher
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). Note that due to the proper handling of hash collisions (hash-table.h:1059), there is no test case that can distinguish the current implementation from the proposed one. * 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.
This commit is contained in:
parent
02cc849474
commit
0f8261eae0
@ -1689,13 +1689,13 @@ equivalent_placeholder_constraints (tree c1, tree c2)
|
|||||||
/* Return a hash value for the placeholder ATOMIC_CONSTR C. */
|
/* Return a hash value for the placeholder ATOMIC_CONSTR C. */
|
||||||
|
|
||||||
hashval_t
|
hashval_t
|
||||||
hash_placeholder_constraint (tree c)
|
iterative_hash_placeholder_constraint (tree c, hashval_t val)
|
||||||
{
|
{
|
||||||
tree t, a;
|
tree t, a;
|
||||||
placeholder_extract_concept_and_args (c, t, a);
|
placeholder_extract_concept_and_args (c, t, a);
|
||||||
|
|
||||||
/* Like hash_tmpl_and_args, but skip the first argument. */
|
/* 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)
|
for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
|
||||||
val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
|
val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
|
||||||
|
@ -8581,7 +8581,7 @@ extern tree_pair finish_type_constraints (tree, tree, tsubst_flags_t);
|
|||||||
extern tree build_constrained_parameter (tree, tree, tree = NULL_TREE);
|
extern tree build_constrained_parameter (tree, tree, tree = NULL_TREE);
|
||||||
extern void placeholder_extract_concept_and_args (tree, tree&, tree&);
|
extern void placeholder_extract_concept_and_args (tree, tree&, tree&);
|
||||||
extern bool equivalent_placeholder_constraints (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 bool deduce_constrained_parameter (tree, tree&, tree&);
|
||||||
extern tree resolve_constraint_check (tree);
|
extern tree resolve_constraint_check (tree);
|
||||||
extern tree check_function_concept (tree);
|
extern tree check_function_concept (tree);
|
||||||
|
@ -4500,7 +4500,12 @@ struct ctp_hasher : ggc_ptr_hash<tree_node>
|
|||||||
val = iterative_hash_object (TEMPLATE_TYPE_LEVEL (t), val);
|
val = iterative_hash_object (TEMPLATE_TYPE_LEVEL (t), val);
|
||||||
val = iterative_hash_object (TEMPLATE_TYPE_IDX (t), val);
|
val = iterative_hash_object (TEMPLATE_TYPE_IDX (t), val);
|
||||||
if (TREE_CODE (t) == TEMPLATE_TYPE_PARM)
|
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)
|
if (TREE_CODE (t) == BOUND_TEMPLATE_TEMPLATE_PARM)
|
||||||
val = iterative_hash_template_arg (TYPE_TI_ARGS (t), val);
|
val = iterative_hash_template_arg (TYPE_TI_ARGS (t), val);
|
||||||
--comparing_specializations;
|
--comparing_specializations;
|
||||||
@ -29581,7 +29586,7 @@ auto_hash::hash (tree t)
|
|||||||
if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
|
if (tree c = NON_ERROR (PLACEHOLDER_TYPE_CONSTRAINTS (t)))
|
||||||
/* Matching constrained-type-specifiers denote the same template
|
/* Matching constrained-type-specifiers denote the same template
|
||||||
parameter, so hash the constraint. */
|
parameter, so hash the constraint. */
|
||||||
return hash_placeholder_constraint (c);
|
return iterative_hash_placeholder_constraint (c, 0);
|
||||||
else
|
else
|
||||||
/* But unconstrained autos are all separate, so just hash the pointer. */
|
/* But unconstrained autos are all separate, so just hash the pointer. */
|
||||||
return iterative_hash_object (t, 0);
|
return iterative_hash_object (t, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user