From patchwork Wed Jan 13 18:38:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1425965 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=nqB/sgY4; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DGGRy3MQqz9sVy for ; Thu, 14 Jan 2021 05:38:52 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 366CF38618CC; Wed, 13 Jan 2021 18:38:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 366CF38618CC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1610563128; bh=5PyulXAZcH4ylO1CuDR/P+2BF6iMpnlaG+863gEgmA4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=nqB/sgY42nGg8+F8qegDa/QIMlxboMBxfL8P99v2nKhuVsuBKP6mMy2mUXBp1S/oL mwsBVD6Xxv7j7dutM2TM1q+HgHt0TWq8bVXoFx0GQTq3fp4lzYErCcJQVuX+trY5/L 09fpv7bzrhrVHbHcmP9vJJvCGbJ5KGTj/sOVAeBA= 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 [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id D3616386EC2F for ; Wed, 13 Jan 2021 18:38:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org D3616386EC2F Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-529-tbgE8SsDPeCgmmpQ1sr93g-1; Wed, 13 Jan 2021 13:38:39 -0500 X-MC-Unique: tbgE8SsDPeCgmmpQ1sr93g-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 8AEB1107ACF7; Wed, 13 Jan 2021 18:38:38 +0000 (UTC) Received: from pdp-11.redhat.com (ovpn-116-17.rdu2.redhat.com [10.10.116.17]) by smtp.corp.redhat.com (Postfix) with ESMTP id 169FC5D9DD; Wed, 13 Jan 2021 18:38:37 +0000 (UTC) To: GCC Patches , Nathan Sidwell , Jason Merrill Subject: [PATCH] c++: Failure to lookup using-decl name [PR98231] Date: Wed, 13 Jan 2021 13:38:24 -0500 Message-Id: <20210113183824.653139-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-15.0 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_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" In r11-4690 we removed the call to finish_nonmember_using_decl in tsubst_expr/DECL_EXPR in the USING_DECL block. This was done not to perform name lookup twice for a non-dependent using-decl, which sounds sensible. However, finish_nonmember_using_decl also pushes the decl's bindings which we still have to do so that we can find the USING_DECL's name later. In this case, we've got a USING_DECL N::operator<< that we are tsubstituting. We already looked it up while parsing the template "foo", and lookup_using_decl stashed the OVERLOAD it found into USING_DECL_DECLS. Now we just have to update the IDENTIFIER_BINDING of the identifier for operator<< with the overload the name is bound to. I didn't want to export push_local_binding so I've introduced a new wrapper. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? gcc/cp/ChangeLog: PR c++/98231 * name-lookup.c (push_using_decl_bindings): New. * name-lookup.h (push_using_decl_bindings): Declare. * pt.c (tsubst_expr): Call push_using_decl_bindings. gcc/testsuite/ChangeLog: PR c++/98231 * g++.dg/lookup/using63.C: New test. --- gcc/cp/name-lookup.c | 10 ++++++++++ gcc/cp/name-lookup.h | 1 + gcc/cp/pt.c | 3 +++ gcc/testsuite/g++.dg/lookup/using63.C | 17 +++++++++++++++++ 4 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/g++.dg/lookup/using63.C base-commit: 285fa338b06b804e72997c4d876ecf08a9c083af diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 5078a0706b9..b4b6c0b81b5 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -9279,4 +9279,14 @@ push_operator_bindings () } } +/* Wrapper around push_local_binding to push the bindings for + a non-member USING_DECL DECL that was found during template parsing. */ + +void +push_using_decl_bindings (tree decl) +{ + push_local_binding (DECL_NAME (decl), USING_DECL_DECLS (decl), + /*using*/true); +} + #include "gt-cp-name-lookup.h" diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index 7172079b274..bac3fa71fc9 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -478,6 +478,7 @@ extern void push_to_top_level (void); extern void pop_from_top_level (void); extern void maybe_save_operator_binding (tree); extern void push_operator_bindings (void); +extern void push_using_decl_bindings (tree); extern void discard_operator_bindings (tree); /* Lower level interface for modules. */ diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 100c35f053c..c27ef6d9fe0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -18133,6 +18133,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, tree scope = USING_DECL_SCOPE (decl); gcc_checking_assert (scope == tsubst (scope, args, complain, in_decl)); + /* We still need to push the bindings so that we can look up + this name later. */ + push_using_decl_bindings (decl); } else if (is_capture_proxy (decl) && !DECL_TEMPLATE_INSTANTIATION (current_function_decl)) diff --git a/gcc/testsuite/g++.dg/lookup/using63.C b/gcc/testsuite/g++.dg/lookup/using63.C new file mode 100644 index 00000000000..fd4bf26f1ad --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/using63.C @@ -0,0 +1,17 @@ +// PR c++/98231 +// { dg-do compile } + +template struct basic_ostream {}; +namespace N { + template + void operator<<(basic_ostream, T); +} +basic_ostream os; + +template void +foo (T value) +{ + using N::operator<<; + os << value; +} +void bar() { foo (1); }