diff options
author | Nathan Sidwell <nathan@acm.org> | 2020-12-02 12:53:23 -0800 |
---|---|---|
committer | Nathan Sidwell <nathan@acm.org> | 2020-12-02 12:59:05 -0800 |
commit | 07589ca2b2c84ec9609861ff5d119ed7413fd9c5 (patch) | |
tree | 36c50abb4cfd8568837fe890353751a51154b8c6 /gcc | |
parent | 4ed34c60a818cc513239844f336fc781a8b47a24 (diff) | |
download | gcc-07589ca2b2c84ec9609861ff5d119ed7413fd9c5.zip gcc-07589ca2b2c84ec9609861ff5d119ed7413fd9c5.tar.gz gcc-07589ca2b2c84ec9609861ff5d119ed7413fd9c5.tar.bz2 |
c++: typename_type structural comparison
For modules we need to compare structurally all the way down. This
means inhibiting typename_type resolution, independent of comparing
specializations.
gcc/cp/
* cp-tree.h (comparing_typenames): Declare.
* pt.c (comparing_typenames): Define.
(spec_hasher::equal): Increment it around comparisons.
* typeck.c (structural_comptypes): Adjust TYPENAME resolution
check.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/cp-tree.h | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 8 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 19 |
3 files changed, 19 insertions, 12 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 41ae13b..156bd6c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5399,6 +5399,10 @@ extern int function_depth; in structrual_comptypes. */ extern int comparing_specializations; +/* Nonzero if we are inside eq_specializations, which affects + resolving of typenames in structural_comptypes. */ +extern int comparing_typenames; + /* In parser.c. */ /* Nonzero if we are parsing an unevaluated operand: an operand to diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 72d6cc3..aa050f5 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -1702,9 +1702,11 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, return spec; } -/* Returns true iff two spec_entry nodes are equivalent. */ - +/* Restricts tree and type comparisons. */ int comparing_specializations; +int comparing_typenames; + +/* Returns true iff two spec_entry nodes are equivalent. */ bool spec_hasher::equal (spec_entry *e1, spec_entry *e2) @@ -1712,6 +1714,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2) int equal; ++comparing_specializations; + ++comparing_typenames; equal = (e1->tmpl == e2->tmpl && comp_template_args (e1->args, e2->args)); if (equal && flag_concepts @@ -1727,6 +1730,7 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2) equal = equivalent_constraints (c1, c2); } --comparing_specializations; + --comparing_typenames; return equal; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 267b284..6294a78 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1256,16 +1256,15 @@ structural_comptypes (tree t1, tree t2, int strict) gcc_assert (TYPE_P (t1) && TYPE_P (t2)); - if (!comparing_specializations) - { - /* TYPENAME_TYPEs should be resolved if the qualifying scope is the - current instantiation. */ - if (TREE_CODE (t1) == TYPENAME_TYPE) - t1 = resolve_typename_type (t1, /*only_current_p=*/true); - - if (TREE_CODE (t2) == TYPENAME_TYPE) - t2 = resolve_typename_type (t2, /*only_current_p=*/true); - } + /* TYPENAME_TYPEs should be resolved if the qualifying scope is the + current instantiation, and we don't care about typename + structural equality. The comparing_typenames check is after the + code check, in order to early-out the common case. */ + if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames) + t1 = resolve_typename_type (t1, /*only_current_p=*/true); + + if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames) + t2 = resolve_typename_type (t2, /*only_current_p=*/true); if (TYPE_PTRMEMFUNC_P (t1)) t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1); |