diff options
author | Patrick Palka <ppalka@redhat.com> | 2022-02-10 08:54:07 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2022-02-10 08:54:07 -0500 |
commit | 3d7341cd731247c2ff6709a000837a6c924247f3 (patch) | |
tree | 8aacb1c758fb742403cf06c8975cc649bbb2833e | |
parent | 3881e1823c5a59d988ddcddcc1e25c5738e228fb (diff) | |
download | gcc-3d7341cd731247c2ff6709a000837a6c924247f3.zip gcc-3d7341cd731247c2ff6709a000837a6c924247f3.tar.gz gcc-3d7341cd731247c2ff6709a000837a6c924247f3.tar.bz2 |
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.cc | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 86b6ddc..1b18e2a 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; } |