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.

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