aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2020-12-02 12:53:23 -0800
committerNathan Sidwell <nathan@acm.org>2020-12-02 12:59:05 -0800
commit07589ca2b2c84ec9609861ff5d119ed7413fd9c5 (patch)
tree36c50abb4cfd8568837fe890353751a51154b8c6 /gcc
parent4ed34c60a818cc513239844f336fc781a8b47a24 (diff)
downloadgcc-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.h4
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/cp/typeck.c19
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);