From: Patrick Palka Date: Thu, 10 Feb 2022 13:54:07 +0000 (-0500) Subject: c++: memfn lookup consistency and dependent using-decls X-Git-Tag: basepoints/gcc-13~1134 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d7341cd731247c2ff6709a000837a6c924247f3;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 86b6ddc634ff..1b18e2a77878 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 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; }