From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 2710D3858401 for ; Mon, 28 Nov 2022 23:57:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 2710D3858401 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1669679823; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=fZO2px7Rh426tF6iqWaP2/q3y39KiMOzg5TFkT3dELE=; b=K4AtEI5MbIHzJ18G5xco3WyO01hY55hDFIHXwZ3uMWbpQfs2aAXafTeWhYpuN96PudFPvY +BHZ13YS1RfLLfhI6TQnkVpuqvyzOlqwPT82vrZyIDpLhOgj9Dy3DEiMat/Ou7RAJwIoRG Cw5ErpWh3pUx3I4uBbUZFmV96v6+m+0= Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-659-m6GT6XZOMZuEGepqo9vEYg-1; Mon, 28 Nov 2022 18:57:01 -0500 X-MC-Unique: m6GT6XZOMZuEGepqo9vEYg-1 Received: by mail-qk1-f199.google.com with SMTP id h8-20020a05620a284800b006b5c98f09fbso24275143qkp.21 for ; Mon, 28 Nov 2022 15:57:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:references:message-id:in-reply-to:subject:cc:to:date :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fZO2px7Rh426tF6iqWaP2/q3y39KiMOzg5TFkT3dELE=; b=CQd0FeR9d7G7XK+ieuqsNd1swhehTKx9/BeXSWkpxsWFXUizHIlbpQqJ2FHy88ALxa sv2UBGRpdeLYS4QyDAd5wqZwkmPIl7Uc0Cg8VOiJDPyz4eQaTv894XCixikYTNzH2J8E OBllKamH32e+Ko7hrQdloBUfoEboHh3VUxIaqN224udgPxiMZ9QF2N2HzwtMvuOdfzfF bLvu1Hn1LDiOOUA0SHi9Zyx5IVSyraTyzQn2yckdSKiUlEXTdsQeHKaDdgsQHwlFzIbs I5NVi2QV/IeFTwt/ziQMmRoCGwtSJT6w3ipVVJXSRSuLN4XflqCIXhTdLTNQJEUopSDL gu7A== X-Gm-Message-State: ANoB5pm+X0UX2q73lJ7ZxeLLr21Jm/qtUVSVf4qxfXb7G30ZWJA/6XHQ 4fjSbs/60pZSS2/ay3nm5Znxa4lv2WfPkaG5AJUeK9xtXBNExyfy3tjGTF7krRebG+lZO5F29Pm gaxCzttgDD2Q8GC7j5w== X-Received: by 2002:a0c:c58d:0:b0:4b8:b07e:7f4c with SMTP id a13-20020a0cc58d000000b004b8b07e7f4cmr27745023qvj.129.1669679821190; Mon, 28 Nov 2022 15:57:01 -0800 (PST) X-Google-Smtp-Source: AA0mqf7zsl5qO/Aqq2xLt423rPqvnBnuy2xcvMSzjQ0VCbkbztoTalj5j/sbhZzahlBQhvwiRqZ81Q== X-Received: by 2002:a0c:c58d:0:b0:4b8:b07e:7f4c with SMTP id a13-20020a0cc58d000000b004b8b07e7f4cmr27745015qvj.129.1669679820938; Mon, 28 Nov 2022 15:57:00 -0800 (PST) Received: from [192.168.1.130] (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id w23-20020ae9e517000000b006f9f3c0c63csm9181823qkf.32.2022.11.28.15.57.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Nov 2022 15:57:00 -0800 (PST) From: Patrick Palka X-Google-Original-From: Patrick Palka Date: Mon, 28 Nov 2022 18:56:59 -0500 (EST) To: Patrick Palka cc: gcc-patches@gcc.gnu.org, jason@redhat.com Subject: Re: [PATCH] c++: TYPENAME_TYPE lookup ignoring non-types [PR107773] In-Reply-To: <20221128212211.940206-1-ppalka@redhat.com> Message-ID: References: <20221128212211.940206-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On Mon, 28 Nov 2022, Patrick Palka wrote: > [temp.res.general]/3 says, in a note, "the usual qualified name lookup > ([basic.lookup.qual]) applies even in the presence of typename". Thus > when resolving a TYPENAME_TYPE, it seems we shouldn't be looking past > non-type members. > > This patch fixes this by passing want_type=false instead of =true during > the member lookup from make_typename_type. An old nearby comment > mentions that we want to continue to set want_type=true when resolving a > nested typename type, but it appears that the nested case is handled by > resolve_typename_type instead (which passes want_type=true appropriately). Whoops, it seems this isn't true -- not all nested TYPENAME_TYPEs are handled by resolve_typename_type, e.g. for T::b in struct a { struct b { typedef void get; }; int b; }; template void f() { typedef typename T::b::get type; } template void f(); Passing want_type=false in make_typename_type causes us to incorrectly reject the TYPENAME_TYPE for T::b here because qualified lookup now finds the data member a::b instead of the nested class of the same name. So it looks like we need a flag to control whether we're dealing with a nested TYPENAME_TYPE or not and to pass want_type=true/false appropriately, I'll poke more tomorrow. > > In passing, use lookup_member instead of lookup_field so that we give a > better diagnostic when a member function is found, and generalize the T > format specifier to D in the diagnostic. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk? > > PR c++/107773 > > gcc/cp/ChangeLog: > > * decl.cc (make_typename_type): Use lookup_member instead of > lookup_field. Pass want_type=false instead of =true. Use D > instead of T format specifier. > * search.cc (lookup_member): Document default argument. > > gcc/testsuite/ChangeLog: > > * g++.dg/template/typename24.C: New test. > * g++.dg/template/typename25.C: New test. > --- > gcc/cp/decl.cc | 7 +++---- > gcc/cp/search.cc | 2 +- > gcc/testsuite/g++.dg/template/typename24.C | 16 ++++++++++++++++ > gcc/testsuite/g++.dg/template/typename25.C | 20 ++++++++++++++++++++ > 4 files changed, 40 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/template/typename24.C > create mode 100644 gcc/testsuite/g++.dg/template/typename25.C > > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc > index 238e72f90da..673e10801a6 100644 > --- a/gcc/cp/decl.cc > +++ b/gcc/cp/decl.cc > @@ -4303,9 +4303,8 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, > member of the current instantiation or a non-dependent base; > lookup will stop when we hit a dependent base. */ > if (!dependent_scope_p (context)) > - /* We should only set WANT_TYPE when we're a nested typename type. > - Then we can give better diagnostics if we find a non-type. */ > - t = lookup_field (context, name, 2, /*want_type=*/true); > + t = lookup_member (context, name, /*protect=*/2, /*want_type=*/false, > + complain); > else > t = NULL_TREE; > > @@ -4357,7 +4356,7 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, > else > { > if (complain & tf_error) > - error ("% names %q#T, which is not a type", > + error ("% names %q#D, which is not a type", > context, name, t); > return error_mark_node; > } > diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc > index 0dbb3be1ee7..e5848ebc620 100644 > --- a/gcc/cp/search.cc > +++ b/gcc/cp/search.cc > @@ -1109,7 +1109,7 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype) > > tree > lookup_member (tree xbasetype, tree name, int protect, bool want_type, > - tsubst_flags_t complain, access_failure_info *afi) > + tsubst_flags_t complain, access_failure_info *afi /* = NULL */) > { > tree rval, rval_binfo = NULL_TREE; > tree type = NULL_TREE, basetype_path = NULL_TREE; > diff --git a/gcc/testsuite/g++.dg/template/typename24.C b/gcc/testsuite/g++.dg/template/typename24.C > new file mode 100644 > index 00000000000..4b1d5e5271b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/typename24.C > @@ -0,0 +1,16 @@ > +// PR c++/107773 > + > +struct a { > + typedef void get; > +}; > + > +struct b : a { > + int get(int i) const; > +}; > + > +template > +void f() { > + typedef typename T::get type; // { dg-error "'int b::get\\(int\\) const', which is not a type" } > +} > + > +template void f(); > diff --git a/gcc/testsuite/g++.dg/template/typename25.C b/gcc/testsuite/g++.dg/template/typename25.C > new file mode 100644 > index 00000000000..4e6b764a97b > --- /dev/null > +++ b/gcc/testsuite/g++.dg/template/typename25.C > @@ -0,0 +1,20 @@ > +// Example 4 from [temp.res.general]/3. > + > +struct A { > + struct X { }; > + int X; > +}; > +struct B { > + struct X { }; > +}; > +template void f(T t) { > + typename T::X x; // { dg-error "'int A::X', which is not a type" } > +} > +void foo() { > + A a; > + B b; > + f(b); // OK, T::X refers to B::X > + // { dg-bogus "" "" { target *-*-* } .-1 } > + f(a); // error: T::X refers to the data member A::X not the struct A::X > + // { dg-message "required from here" "" { target *-*-* } .-1 } > +} > -- > 2.39.0.rc0.33.g815c1e8202 > >