aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-02-10 08:54:07 -0500
committerPatrick Palka <ppalka@redhat.com>2022-02-10 08:54:07 -0500
commit3d7341cd731247c2ff6709a000837a6c924247f3 (patch)
tree8aacb1c758fb742403cf06c8975cc649bbb2833e
parent3881e1823c5a59d988ddcddcc1e25c5738e228fb (diff)
c++: memfn lookup consistency and dependent using-decls
Rather than not doing any filtering when filter_memfn_lookup encounters a dependent using-decl, handle this case less imprecisely by holding on to the members in the new lookup set that come from a base, i.e. that could plausibly have been introduced by that using-decl, and filtering the rest as usual. This is still imperfect, but it's closer to the correct answer than the previous behavior was. gcc/cp/ChangeLog: * pt.cc (filter_memfn_lookup): Handle dependent USING_DECL better.
-rw-r--r--gcc/cp/pt.cc26
1 files changed, 17 insertions, 9 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 86b6ddc634f..1b18e2a7787 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -16327,15 +16327,20 @@ filter_memfn_lookup (tree oldfns, tree newfns, tree newtype)
/* Record all member functions from the old lookup set OLDFNS into
VISIBLE_SET. */
hash_set<tree> visible_set;
+ bool seen_dep_using = false;
for (tree fn : lkp_range (oldfns))
{
if (TREE_CODE (fn) == USING_DECL)
{
- /* FIXME: Punt on (dependent) USING_DECL for now; mapping
- a dependent USING_DECL to the member functions it introduces
- seems tricky. */
+ /* Imprecisely handle dependent using-decl by keeping all members
+ in the new lookup set that are defined in a base class, i.e.
+ members that could plausibly have been introduced by this
+ dependent using-decl.
+ FIXME: Track which members are introduced by a dependent
+ using-decl precisely, perhaps by performing another lookup
+ from the substituted USING_DECL_SCOPE. */
gcc_checking_assert (DECL_DEPENDENT_P (fn));
- return newfns;
+ seen_dep_using = true;
}
else
visible_set.add (fn);
@@ -16343,12 +16348,13 @@ filter_memfn_lookup (tree oldfns, tree newfns, tree newtype)
/* Returns true iff (a less specialized version of) FN appeared in
the old lookup set OLDFNS. */
- auto visible_p = [newtype, &visible_set] (tree fn) {
+ auto visible_p = [newtype, seen_dep_using, &visible_set] (tree fn) {
if (DECL_CONTEXT (fn) != newtype)
/* FN is a member function from a base class, introduced via a
- non-dependent using-decl; look in the old lookup set for
- FN exactly. */
- return visible_set.contains (fn);
+ using-decl; if it might have been introduced by a dependent
+ using-decl then just conservatively keep it, otherwise look
+ in the old lookup set for FN exactly. */
+ return seen_dep_using || visible_set.contains (fn);
else if (TREE_CODE (fn) == TEMPLATE_DECL)
/* FN is a member function template from the current class;
look in the old lookup set for the TEMPLATE_DECL from which
@@ -16382,7 +16388,9 @@ filter_memfn_lookup (tree oldfns, tree newfns, tree newtype)
filtered_fns = lookup_add (fn, filtered_fns);
filtered_size++;
}
- gcc_checking_assert (filtered_size == visible_set.elements ());
+ gcc_checking_assert (seen_dep_using
+ ? filtered_size >= visible_set.elements ()
+ : filtered_size == visible_set.elements ());
return filtered_fns;
}