On Wed, 8 Jan 2025, Patrick Palka wrote:

> On Thu, Dec 12, 2024 at 2:34 PM Patrick Palka <ppa...@redhat.com> wrote:
> >
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk?  The older regression does not seem worth fixing.

Oops, does not seem worth fixing _on release branches_ rather.

> 
> Ping.
> 
> >
> > -- >8 --
> >
> > In the first testcase we're overeagerly diagnosing qualified name lookup
> > failure for f from the current instantiation B<T>::C ahead of time
> > because we (correctly) deem C to not have any direct dependent bases:
> > its only base is B<T> which is part of the current instantiation and
> > therefore not a dependent base, and we decide it's safe to diagnose name
> > lookup failure ahead of time.
> >
> > But this testcase demonstrates it's not enough to consider only direct
> > dependent bases: f is defined in A<T> which is a dependent base of
> > B<T>, so qualified name lookup won't search it ahead of time and in
> > turn name lookup won't be exhaustive, and so it's wrong to diagnose
> > lookup failure ahead of time.  This ultimately suggests that
> > any_dependent_bases_p needs to consider indirect bases as well.
> >
> > It seems sufficient to recurse into any !BINFO_DEPENDENT_BASE_P base
> > since the recursive call will exit early for non-dependent types.
> > So effectively we'll only recurse into bases belonging to the current
> > instantiation.
> >
> > I considered making only dependentish_scope_p consider indirect
> > dependent bases, but it seems other any_dependent_bases_p callers
> > also want this behavior, e.g. build_new_method_call for benefit of
> > the second testcase (which is an even older regression since GCC 7).
> >
> >         PR c++/117993
> >
> > gcc/cp/ChangeLog:
> >
> >         * search.cc (any_dependent_bases_p): Recurse into bases (of
> >         dependent type) that are not BINFO_DEPENDENT_BASE_P.  Document
> >         default argument.
> >
> > gcc/testsuite/ChangeLog:
> >
> >         * g++.dg/template/dependent-base4.C: New test.
> >         * g++.dg/template/dependent-base5.C: New test.
> > ---
> >  gcc/cp/search.cc                              |  5 ++--
> >  .../g++.dg/template/dependent-base4.C         | 23 +++++++++++++++++++
> >  .../g++.dg/template/dependent-base5.C         | 22 ++++++++++++++++++
> >  3 files changed, 48 insertions(+), 2 deletions(-)
> >  create mode 100644 gcc/testsuite/g++.dg/template/dependent-base4.C
> >  create mode 100644 gcc/testsuite/g++.dg/template/dependent-base5.C
> >
> > diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc
> > index d438e18b74b..8a65dd3b68e 100644
> > --- a/gcc/cp/search.cc
> > +++ b/gcc/cp/search.cc
> > @@ -2843,7 +2843,7 @@ original_binfo (tree binfo, tree here)
> >     TYPE).  */
> >
> >  bool
> > -any_dependent_bases_p (tree type)
> > +any_dependent_bases_p (tree type /* = current_nonlambda_class_type () */)
> >  {
> >    if (!type || !CLASS_TYPE_P (type) || !uses_template_parms (type))
> >      return false;
> > @@ -2858,7 +2858,8 @@ any_dependent_bases_p (tree type)
> >    unsigned i;
> >    tree base_binfo;
> >    FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, 
> > base_binfo)
> > -    if (BINFO_DEPENDENT_BASE_P (base_binfo))
> > +    if (BINFO_DEPENDENT_BASE_P (base_binfo)
> > +       || any_dependent_bases_p (BINFO_TYPE (base_binfo)))
> >        return true;
> >
> >    return false;
> > diff --git a/gcc/testsuite/g++.dg/template/dependent-base4.C 
> > b/gcc/testsuite/g++.dg/template/dependent-base4.C
> > new file mode 100644
> > index 00000000000..84e53b5f3fb
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/template/dependent-base4.C
> > @@ -0,0 +1,23 @@
> > +// PR c++/117993
> > +
> > +template<class T>
> > +struct A {
> > +  void f();
> > +  typedef void type;
> > +};
> > +
> > +template<class T>
> > +struct B : A<T> {
> > +  template<class U> struct C;
> > +};
> > +
> > +template<class T>
> > +template<class U>
> > +struct B<T>::C : B {
> > +  void g(C& c) {
> > +    this->f();           // { dg-bogus "member" }
> > +    c.f();               // { dg-bogus "member" }
> > +    C::f();              // { dg-bogus "member" }
> > +    typename C::type* p; // { dg-bogus "not name a type" }
> > +  }
> > +};
> > diff --git a/gcc/testsuite/g++.dg/template/dependent-base5.C 
> > b/gcc/testsuite/g++.dg/template/dependent-base5.C
> > new file mode 100644
> > index 00000000000..2e9cdaa242b
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/template/dependent-base5.C
> > @@ -0,0 +1,22 @@
> > +template<class T>
> > +struct A { };
> > +
> > +template<class T>
> > +struct B : A<T> {
> > +  template<class U> struct C;
> > +};
> > +
> > +struct D { void f(); };
> > +
> > +template<class T>
> > +template<class U>
> > +struct B<T>::C : B {
> > +  void g() {
> > +    D::f(); // { dg-bogus "without object" }
> > +  }
> > +};
> > +
> > +template<>
> > +struct A<int> : D { };
> > +
> > +template struct B<int>::C<int>;
> > --
> > 2.47.1.440.gcaacdb5dfd
> >
> 

Reply via email to