public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Andrew Pinski <pinskia@gmail.com>
To: Patrick Palka <ppalka@redhat.com>
Cc: gcc-patches@gcc.gnu.org, jason@redhat.com
Subject: Re: [PATCH] c++: 'typename T::X' vs 'struct T::X' lookup [PR109420]
Date: Fri, 3 May 2024 13:36:20 -0700	[thread overview]
Message-ID: <CA+=Sn1nY0TAJco-YF0OBcHR_v29iWBMoupLOm3ECj_vdAX9VtQ@mail.gmail.com> (raw)
In-Reply-To: <3be49cfe-e9ff-19c6-79d4-8a03874a6fba@idea>

On Fri, May 3, 2024 at 8:08 AM Patrick Palka <ppalka@redhat.com> wrote:
>
> Hey Andrew,
>
> On Wed, 5 Apr 2023, Andrew Pinski wrote:
>
> > On Wed, Apr 5, 2023 at 10:32 AM Patrick Palka via Gcc-patches
> > <gcc-patches@gcc.gnu.org> wrote:
> > >
> > > On Wed, 5 Apr 2023, Patrick Palka wrote:
> > >
> > > > r13-6098-g46711ff8e60d64 made make_typename_type no longer ignore
> > > > non-types during the lookup, unless the TYPENAME_TYPE in question was
> > > > followed by the :: scope resolution operator.  But there is another
> > > > exception to this rule: we need to ignore non-types during the lookup
> > > > also if the TYPENAME_TYPE was named with a tag other than 'typename',
> > > > such as 'struct' or 'enum', as per [dcl.type.elab]/5.
> > > >
> > > > This patch implements this additional exception.  It occurred to me that
> > > > the tf_qualifying_scope flag is probably unnecessary if we'd use the
> > > > scope_type tag more thoroughly, but that requires parser changes that
> > > > are probably too risky at this stage.  (I'm working on addressing the
> > > > FIXME/TODOs here for GCC 14.)
> > > >
> > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > > > trunk?
> > > >
> > > >       PR c++/109420
> > > >
> > > > gcc/cp/ChangeLog:
> > > >
> > > >       * decl.cc (make_typename_type): Also ignore non-types during
> > > >       the lookup if tag_type is something other than none_type or
> > > >       typename_type.
> > > >       * pt.cc (tsubst) <case TYPENAME_TYPE>: Pass class_type or
> > > >       enum_type as tag_type to make_typename_type as appropriate
> > > >       instead of always passing typename_type.
> > > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > >       * g++.dg/template/typename27.C: New test.
> > > > ---
> > > >  gcc/cp/decl.cc                             |  9 ++++++++-
> > > >  gcc/cp/pt.cc                               |  9 ++++++++-
> > > >  gcc/testsuite/g++.dg/template/typename27.C | 19 +++++++++++++++++++
> > > >  3 files changed, 35 insertions(+), 2 deletions(-)
> > > >  create mode 100644 gcc/testsuite/g++.dg/template/typename27.C
> > > >
> > > > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> > > > index 5369714f9b3..a0a20c5accc 100644
> > > > --- a/gcc/cp/decl.cc
> > > > +++ b/gcc/cp/decl.cc
> > > > @@ -4307,7 +4307,14 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
> > > >       lookup will stop when we hit a dependent base.  */
> > > >    if (!dependent_scope_p (context))
> > > >      {
> > > > -      bool want_type = (complain & tf_qualifying_scope);
> > > > +      /* As per [dcl.type.elab]/5 and [temp.res.general]/3, ignore non-types if
> > > > +      the tag corresponds to a class-key or 'enum' (or is scope_type), or if
> > > > +      this typename is followed by :: as per [basic.lookup.qual.general]/1.
> > > > +      TODO: If we'd set the scope_type tag accurately on all TYPENAME_TYPEs
> > > > +      that are followed by :: then we wouldn't need the tf_qualifying_scope
> > > > +      flag.  */
> > > > +      bool want_type = (tag_type != none_type && tag_type != typename_type)
> > > > +     || (complain & tf_qualifying_scope);
> > >
> > > Here's v2 which just slightly improves this comment.  I reckon [basic.lookup.elab]
> > > is a better reference than [dcl.type.elab]/5 for justifying why the
> > > lookup should be type-only for class-key and 'enum' TYPENAME_TYPEs.
> > >
> > > -- >8 --
> > >
> > >         PR c++/109420
> > >
> > > gcc/cp/ChangeLog:
> > >
> > >         * decl.cc (make_typename_type): Also ignore non-types during the
> > >         lookup if tag_type corresponds to an elaborated-type-specifier.
> > >         * pt.cc (tsubst) <case TYPENAME_TYPE>: Pass class_type or
> > >         enum_type as tag_type to make_typename_type as appropriate
> > >         instead of always passing typename_type.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > >         * g++.dg/template/typename27.C: New test.
> > > ---
> > >  gcc/cp/decl.cc                             | 12 +++++++++++-
> > >  gcc/cp/pt.cc                               |  9 ++++++++-
> > >  gcc/testsuite/g++.dg/template/typename27.C | 19 +++++++++++++++++++
> > >  3 files changed, 38 insertions(+), 2 deletions(-)
> > >  create mode 100644 gcc/testsuite/g++.dg/template/typename27.C
> > >
> > > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> > > index 5369714f9b3..772c059dc2c 100644
> > > --- a/gcc/cp/decl.cc
> > > +++ b/gcc/cp/decl.cc
> > > @@ -4307,7 +4307,17 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
> > >       lookup will stop when we hit a dependent base.  */
> > >    if (!dependent_scope_p (context))
> > >      {
> > > -      bool want_type = (complain & tf_qualifying_scope);
> > > +      /* We generally don't ignore non-types during TYPENAME_TYPE lookup
> > > +        (as per [temp.res.general]/3), unless
> > > +          - the tag corresponds to a class-key or 'enum' so
> > > +            [basic.lookup.elab] applies, or
> > > +          - the tag corresponds to scope_type or tf_qualifying_scope is
> > > +            set so [basic.lookup.qual]/1 applies.
> > > +        TODO: If we'd set/track the scope_type tag thoroughly on all
> > > +        TYPENAME_TYPEs that are followed by :: then we wouldn't need the
> > > +        tf_qualifying_scope flag.  */
> > > +      bool want_type = (tag_type != none_type && tag_type != typename_type)
> > > +       || (complain & tf_qualifying_scope);
> > >        t = lookup_member (context, name, /*protect=*/2, want_type, complain);
> > >      }
> > >    else
> > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > > index 821e0035c08..09559c88f29 100644
> > > --- a/gcc/cp/pt.cc
> > > +++ b/gcc/cp/pt.cc
> > > @@ -16580,9 +16580,16 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
> > >               return error_mark_node;
> > >           }
> > >
> > > +       /* FIXME: TYPENAME_IS_CLASS_P conflates 'union' vs 'struct' vs 'class'
> > > +          tags.  TYPENAME_TYPE should probably remember the exact tag that
> > > +          was written.  */
> >
> > Yes I had a patch for that but I submitted during stage 4 of GCC 12
> > and never updated again during stage 1 of GCC 13. I hope to submit it
> > again with updated changes post this patch.
>
> Do you still plan on submitting a patch for this?  It would be great to
> fix this for GCC 15 :)

I think I will be getting back to that patch the first week of June
and submitting an updated version based on the previous review. I have
a few other patches I am working on before I can start working on that
one.

Thanks,
Andrew

>
> >
> > Thanks,
> > Andrew
> >
> >
> > > +       enum tag_types tag
> > > +         = TYPENAME_IS_CLASS_P (t) ? class_type
> > > +         : TYPENAME_IS_ENUM_P (t) ? enum_type
> > > +         : typename_type;
> > >         tsubst_flags_t tcomplain = complain | tf_keep_type_decl;
> > >         tcomplain |= tst_ok_flag | qualifying_scope_flag;
> > > -       f = make_typename_type (ctx, f, typename_type, tcomplain);
> > > +       f = make_typename_type (ctx, f, tag, tcomplain);
> > >         if (f == error_mark_node)
> > >           return f;
> > >         if (TREE_CODE (f) == TYPE_DECL)
> > > diff --git a/gcc/testsuite/g++.dg/template/typename27.C b/gcc/testsuite/g++.dg/template/typename27.C
> > > new file mode 100644
> > > index 00000000000..61b3efd998e
> > > --- /dev/null
> > > +++ b/gcc/testsuite/g++.dg/template/typename27.C
> > > @@ -0,0 +1,19 @@
> > > +// PR c++/109420
> > > +
> > > +struct A {
> > > +  struct X { };
> > > +  int X;
> > > +};
> > > +
> > > +struct B {
> > > +  enum E { };
> > > +  enum F { E };
> > > +};
> > > +
> > > +template<class T, class U>
> > > +void f() {
> > > +  struct T::X x; // OK, lookup ignores the data member 'int A::X'
> > > +  enum U::E e;   // OK, lookup ignores the enumerator 'B::F::E'
> > > +}
> > > +
> > > +template void f<A, B>();
> > > --
> > > 2.40.0.153.g6369acd968
> > >
> >
> >

  reply	other threads:[~2024-05-03 20:36 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-04-05 16:59 Patrick Palka
2023-04-05 17:31 ` Patrick Palka
2023-04-05 17:35   ` Andrew Pinski
2023-04-18 12:13     ` Patrick Palka
2024-05-03 15:08     ` Patrick Palka
2024-05-03 20:36       ` Andrew Pinski [this message]
2023-04-13 19:09   ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CA+=Sn1nY0TAJco-YF0OBcHR_v29iWBMoupLOm3ECj_vdAX9VtQ@mail.gmail.com' \
    --to=pinskia@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=ppalka@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).