From patchwork Wed Jan 6 18:19:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Palka X-Patchwork-Id: 1423030 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=cicew8xu; 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 4D9yM32S5Vz9sTv for ; Thu, 7 Jan 2021 05:19:42 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 07C713950C7E; Wed, 6 Jan 2021 18:19:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 07C713950C7E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1609957180; bh=lWEU/7cJ10YgfCKVciBdIIs9P/NmXF06C66EZGI27Zw=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=cicew8xuxwvVsNxbxKawkvvAsScDbEJ1JhHra8ysOn4tur5ztdLoekW/SXGqEic5r Oup18ecNlzpkv7qaIa5UMM3YO/FaKuxlevcclJ7UvI60ZlttpYxVwg9Xd54u5LSPlr m5b30JxSNiMZUb55kutIaMlApnalcnE1GNmcYqNg= 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 75538384A40A for ; Wed, 6 Jan 2021 18:19:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 75538384A40A Received: from mail-qt1-f197.google.com (mail-qt1-f197.google.com [209.85.160.197]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-257-1DWIOfXeOMOsXB9tS3e5EA-1; Wed, 06 Jan 2021 13:19:35 -0500 X-MC-Unique: 1DWIOfXeOMOsXB9tS3e5EA-1 Received: by mail-qt1-f197.google.com with SMTP id f7so2904494qtj.7 for ; Wed, 06 Jan 2021 10:19:35 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=lWEU/7cJ10YgfCKVciBdIIs9P/NmXF06C66EZGI27Zw=; b=rLGezTlMXy6v6dOb0ZAOOJp5nZ0CWeIS8dEHp/2DH99DcK3SrJy4aMReP4SLFICegy TrJu9KfjANlO44scpUkCfUz/Cf/E9pHtSEQwgQow8hxXbBCFcwddXagT95mbSh9YXz5F 1extr2TmfAstnW2yrjSuTaZ2nYuAb8Kl7hpJcyf65EcfXamvEjav47Yx6Xj91OYyzjB+ DvX0N2t2253Kx/FJntCN5QHju97zUVthRj2iKZaCqpfcSqckV38Yl1/Jk0uRvepp8x1a TfLjs+K0UTzYp4ezCR48ARjOz+hLeiob3yxLcn2PttmZlg4iTVdaTb1iQOMMbbi+heP4 CMTw== X-Gm-Message-State: AOAM530cn5fG4Gq8BzKtmydlETXZK8dTZ5cWM9yGm1nyDiXbSnQjvJJb 32xSQHnJjf1FhIx8olrpjfFUO1Etx5g7Vt1P6RdbWXOENRDFwmNqKSZkYlYjQU+esC+uLReIj2m g7/GqdIgAPq63UD8JRaFsReoXod0KkOUG5ckriRmLN0FSSHJmeqnIJ5JXOwigmsRRnF4= X-Received: by 2002:aed:2986:: with SMTP id o6mr5188077qtd.274.1609957174984; Wed, 06 Jan 2021 10:19:34 -0800 (PST) X-Google-Smtp-Source: ABdhPJw5sVquifUF9GLymtOHwv6j00KUFonPmBZNMJrLCos33kgi1zjzg6nQpKlCZ1H/q+2lxt5vpg== X-Received: by 2002:aed:2986:: with SMTP id o6mr5188043qtd.274.1609957174625; Wed, 06 Jan 2021 10:19:34 -0800 (PST) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id m190sm1785184qkb.42.2021.01.06.10.19.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Jan 2021 10:19:33 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] c++: Fix access checking of scoped non-static member [PR98515] Date: Wed, 6 Jan 2021 13:19:32 -0500 Message-Id: <20210106181932.1393432-1-ppalka@redhat.com> X-Mailer: git-send-email 2.30.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-16.4 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: Patrick Palka via Gcc-patches From: Patrick Palka Reply-To: Patrick Palka Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" In the first testcase below, we incorrectly reject the use of the protected non-static member A::var0 from C::g() because check_accessibility_of_qualified_id, at template parse time, determines that the access doesn't go through 'this'. (This happens because the dependent base B of C doesn't have a binfo object, so it appears to DERIVED_FROM_P that A is not an indirect base of C.) From there we create the corresponding deferred access check, which we then perform at instantiation time and which (unsurprisingly) fails. The problem ultimately seems to be that we can't, in general, know whether a use of a scoped non-static member goes through 'this' until instantiation time, as the second testcase below demonstrates. So this patch makes check_accessibility_of_qualified_id punt in this situation. Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to commit? gcc/cp/ChangeLog: PR c++/98515 * semantics.c (check_accessibility_of_qualified_id): Punt if we're checking the access of a scoped non-static member at class template parse time. gcc/testsuite/ChangeLog: PR c++/98515 * g++.dg/template/access32.C: New test. * g++.dg/template/access33.C: New test. --- gcc/cp/semantics.c | 20 +++++++++++++++----- gcc/testsuite/g++.dg/template/access32.C | 8 ++++++++ gcc/testsuite/g++.dg/template/access33.C | 9 +++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/access32.C create mode 100644 gcc/testsuite/g++.dg/template/access33.C diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b448efe024a..f52b2e4d1e7 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2107,14 +2107,24 @@ check_accessibility_of_qualified_id (tree decl, /* If the reference is to a non-static member of the current class, treat it as if it were referenced through `this'. */ - tree ct; if (DECL_NONSTATIC_MEMBER_P (decl) - && current_class_ptr - && DERIVED_FROM_P (scope, ct = current_nonlambda_class_type ())) - qualifying_type = ct; + && current_class_ptr) + { + if (dependent_type_p (TREE_TYPE (current_class_ptr))) + /* In general we can't know whether this access goes through `this' + until instantiation of the current class. Punt now, or else + we might create a deferred access check that's relative to the + wrong class. We'll check this access again after substitution, + e.g. from tsubst_qualified_id. */ + return true; + + if (tree current = current_nonlambda_class_type ()) + if (DERIVED_FROM_P (scope, current)) + qualifying_type = current; + } /* Otherwise, use the type indicated by the nested-name-specifier. */ - else + if (!qualifying_type) qualifying_type = nested_name_specifier; } else diff --git a/gcc/testsuite/g++.dg/template/access32.C b/gcc/testsuite/g++.dg/template/access32.C new file mode 100644 index 00000000000..08faa9f0f97 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access32.C @@ -0,0 +1,8 @@ +// PR c++/98515 +// { dg-do compile } + +struct A { protected: int var0; }; +template struct B : public A { }; +template struct C : public B { void g(); }; +template void C::g() { A::var0++; } +template class C; diff --git a/gcc/testsuite/g++.dg/template/access33.C b/gcc/testsuite/g++.dg/template/access33.C new file mode 100644 index 00000000000..9fb9b9a1236 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access33.C @@ -0,0 +1,9 @@ +// PR c++/98515 +// { dg-do compile } + +struct A { protected: int var0; }; +template struct B : public A { }; +template struct C : public B { void g(); }; +template void C::g() { A::var0++; } // { dg-error "protected|invalid" } +template <> struct B { }; +template class C;