From patchwork Wed Nov 29 15:45:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1869731 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=StYeJMj4; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.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 ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SgNvZ6Rcyz1yST for ; Thu, 30 Nov 2023 02:45:46 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CF088385C017 for ; Wed, 29 Nov 2023 15:45:41 +0000 (GMT) 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.129.124]) by sourceware.org (Postfix) with ESMTPS id F07B83858D3C for ; Wed, 29 Nov 2023 15:45:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org F07B83858D3C Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org F07B83858D3C Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701272731; cv=none; b=B708qex0hY40Z8hirJaqXsUQFCI0k0L5XeQH6GZzCCVz/iCiWCo/OWLxvuhlhu2waRKL29In76mZa1GaFde+djfBy4fL8qp59iEaQRbImwSmeRr+h5SXYfQuprH0ntuSg2vDRWemheOly17Xm/vCt2Sjel8S6rcyM1CJIcGhabk= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701272731; c=relaxed/simple; bh=UoB+Fp3zZRMwHPxUEHs9FjKbbaFRXPp43Jx+2dLTOko=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=FqIJUeYPjsCtkatwIY+gzX+s2flMoGWGuzcKPHSiZSM0chh/5eb7dhFExcIFWA1PrP+BKrfCGhvpC2Mg7+TM1grAJmeuEyVJJ6tiL+wzXLDsWS8bvhOK5LG+Vcw3pW+hNG6FRpX+DrRQrzRpKS1OHZRCTe7gMCe99eV93K3x7BY= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1701272729; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cjBLX4DZqc2sjdSv8VH36/SQwQ64LQBY+kkwb8eyGuY=; b=StYeJMj4nXT6goT8x2WyufRPP44Q8Nb2mD1LaA6NuSxE0HsveQn8IiwEtnbSNWVm7SvzoR as5HV6Gld3B+fMIVbDYFDyEPeP6OHWdEuuaRlhFzLgTkrio3bSxQVHXRT81DmYqYo1XrSo CGOlq21SQpDnjlb5W+LpoCIkgWYmviA= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-341-h7xRnMxgN0OsNxaJlM8jWQ-1; Wed, 29 Nov 2023 10:45:28 -0500 X-MC-Unique: h7xRnMxgN0OsNxaJlM8jWQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id BB0831019C86 for ; Wed, 29 Nov 2023 15:45:27 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.9.148]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9960B1C060AE; Wed, 29 Nov 2023 15:45:27 +0000 (UTC) From: Marek Polacek To: GCC Patches , Jason Merrill Subject: [PATCH] c++: wrong ambiguity in accessing static field [PR112744] Date: Wed, 29 Nov 2023 10:45:12 -0500 Message-ID: <20231129154512.428173-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.7 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 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_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? Now that I'm posting this patch, I think you'll probably want me to use ba_any unconditionally. That works too; g++.dg/tc1/dr52.C just needs a trivial testsuite tweak: 'C' is not an accessible base of 'X' v. 'C' is an inaccessible base of 'X' We should probably unify those messages... -- >8 -- Given struct A { constexpr static int a = 0; }; struct B : A {}; struct C : A {}; struct D : B, C {}; we give the "'A' is an ambiguous base of 'D'" error for D{}.A::a; which seems wrong: 'a' is a static data member so there is only one copy so it can be unambiguously referred to even if there are multiple A objects. clang++/MSVC/icx agree. PR c++/112744 gcc/cp/ChangeLog: * typeck.cc (finish_class_member_access_expr): When accessing a static data member, use ba_any for lookup_base. gcc/testsuite/ChangeLog: * g++.dg/lookup/scoped11.C: New test. * g++.dg/lookup/scoped12.C: New test. * g++.dg/lookup/scoped13.C: New test. --- gcc/cp/typeck.cc | 21 ++++++++++++++++++--- gcc/testsuite/g++.dg/lookup/scoped11.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/lookup/scoped12.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/lookup/scoped13.C | 14 ++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/scoped11.C create mode 100644 gcc/testsuite/g++.dg/lookup/scoped12.C create mode 100644 gcc/testsuite/g++.dg/lookup/scoped13.C base-commit: 3d104d93a7011146b0870ab160613147adb8d9b3 diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index e995fb6ddd7..c4de8bb2616 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -3476,7 +3476,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, name, scope); return error_mark_node; } - + if (TREE_SIDE_EFFECTS (object)) val = build2 (COMPOUND_EXPR, TREE_TYPE (val), object, val); return val; @@ -3493,9 +3493,24 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, return error_mark_node; } + /* NAME may refer to a static data member, in which case there is + one copy of the data member that is shared by all the objects of + the class. So NAME can be unambiguously referred to even if + there are multiple indirect base classes containing NAME. */ + const base_access ba = [scope, name] () + { + if (identifier_p (name)) + { + tree m = lookup_member (scope, name, /*protect=*/0, + /*want_type=*/false, tf_none); + if (!m || VAR_P (m)) + return ba_any; + } + return ba_check; + } (); + /* Find the base of OBJECT_TYPE corresponding to SCOPE. */ - access_path = lookup_base (object_type, scope, ba_check, - NULL, complain); + access_path = lookup_base (object_type, scope, ba, NULL, complain); if (access_path == error_mark_node) return error_mark_node; if (!access_path) diff --git a/gcc/testsuite/g++.dg/lookup/scoped11.C b/gcc/testsuite/g++.dg/lookup/scoped11.C new file mode 100644 index 00000000000..be743522fce --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/scoped11.C @@ -0,0 +1,14 @@ +// PR c++/112744 +// { dg-do compile } + +struct A { const static int a = 0; }; +struct B : A {}; +struct C : A {}; +struct D : B, C {}; + +int main() +{ + D d; + (void) d.a; + (void) d.A::a; +} diff --git a/gcc/testsuite/g++.dg/lookup/scoped12.C b/gcc/testsuite/g++.dg/lookup/scoped12.C new file mode 100644 index 00000000000..ffa145598fd --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/scoped12.C @@ -0,0 +1,14 @@ +// PR c++/112744 +// { dg-do compile } + +class A { const static int a = 0; }; +struct B : A {}; +struct C : A {}; +struct D : B, C {}; + +int main() +{ + D d; + (void) d.a; // { dg-error "private" } + (void) d.A::a; // { dg-error "private" } +} diff --git a/gcc/testsuite/g++.dg/lookup/scoped13.C b/gcc/testsuite/g++.dg/lookup/scoped13.C new file mode 100644 index 00000000000..970e1aa833e --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/scoped13.C @@ -0,0 +1,14 @@ +// PR c++/112744 +// { dg-do compile } + +struct A { const static int a = 0; }; +struct B : A {}; +struct C : A {}; +struct D : B, C {}; + +int main() +{ + D d; + (void) d.x; // { dg-error ".struct D. has no member named .x." } + (void) d.A::x; // { dg-error ".struct A. has no member named .x." } +}