From patchwork Mon Nov 28 21:22:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 61198 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BA863385841E for ; Mon, 28 Nov 2022 21:22:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BA863385841E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1669670565; bh=MBRHyXAPWVs0mUR9/8UnvuclAQ5mWXGQrCCoKfrOI1c=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=jlJJELVRIQWJlYftCgqeKaGZ5lFqWz8+zkMJwbU7MUNfDp4NwG2+3Zawld+PMGwKE HdwLldYrxnMfJfIwNy7+MlCycKUfmSP9XMgiFAFc2+M4HiXwpxLS3TfqP9wT472nuA S5z+U+LdOgacJHye/giiH2YmClbXWoYT65UmUXZ8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 3A32A3858408 for ; Mon, 28 Nov 2022 21:22:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3A32A3858408 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-400-iQWkEynlMkKLNR_X73UiMQ-1; Mon, 28 Nov 2022 16:22:15 -0500 X-MC-Unique: iQWkEynlMkKLNR_X73UiMQ-1 Received: by mail-qv1-f70.google.com with SMTP id w1-20020a056214012100b004c6ecf32001so11353328qvs.8 for ; Mon, 28 Nov 2022 13:22:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=MBRHyXAPWVs0mUR9/8UnvuclAQ5mWXGQrCCoKfrOI1c=; b=iahQdV8UsfSedrHFwdWyDZO74RYLjxMJSYfbR9NtvPveo4FjGNTEWGwiJbKc8+IpRM Z6LnvgW817i88AMXTp/iGX0kqQaZ81o4zzoR2F1iP6VLFezXC7ffQmiMdBNV7KVe4ALh wsN2GQmJqUA4WGyfG80pmqAAY/oKklQSjbtA/XRj3EGdQVq6cob4WfOGNTwUdpuP7mv6 BVkKhrYBZW8pKkJofEAUYJ625o2snINiduzlhiZVL9T6MxMEVZ721AArPRtdd+P96dI3 uXvmE7iVh25KvpFGtpy95qRM7WE2kxF8Ygebqwb9ltrYstMIWiCzsS0tna8LndjlKuHQ zkzA== X-Gm-Message-State: ANoB5pnbkHozY8ZbeeknK3RKbhS9TsRuWWsFAU4HtdtlPDDlewHYd/rG tlxBthqoYZ8mBrSqyiWIXpp/LBP+fzSqSYQyJfBI848VzUYmXUbuarv/aeOyDlRGnPAkRXHjQ9N QyOywAh28/psy6Dxp/eZuKWNnusxgf7Yolurv84pm4nF6WlGGm+7YH9U3jUtTx+tq66k= X-Received: by 2002:ad4:5291:0:b0:4c6:e1ba:b1c with SMTP id v17-20020ad45291000000b004c6e1ba0b1cmr19779687qvr.73.1669670533864; Mon, 28 Nov 2022 13:22:13 -0800 (PST) X-Google-Smtp-Source: AA0mqf5YSkteg2euHrZ5scUJammeZpifviw+IxGTUB1edlUU8CSwFi9vR0gOYcRIi9IQ856Gt/U9vA== X-Received: by 2002:ad4:5291:0:b0:4c6:e1ba:b1c with SMTP id v17-20020ad45291000000b004c6e1ba0b1cmr19779656qvr.73.1669670533446; Mon, 28 Nov 2022 13:22:13 -0800 (PST) Received: from localhost.localdomain (ool-457670bb.dyn.optonline.net. [69.118.112.187]) by smtp.gmail.com with ESMTPSA id 189-20020a3705c6000000b006fab416015csm8970483qkf.25.2022.11.28.13.22.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Nov 2022 13:22:12 -0800 (PST) To: gcc-patches@gcc.gnu.org Cc: jason@redhat.com, Patrick Palka Subject: [PATCH] c++: TYPENAME_TYPE lookup ignoring non-types [PR107773] Date: Mon, 28 Nov 2022 16:22:11 -0500 Message-Id: <20221128212211.940206-1-ppalka@redhat.com> X-Mailer: git-send-email 2.39.0.rc0.33.g815c1e8202 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.7 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" [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). 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 } +}