From patchwork Wed Nov 29 22:01:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 171602 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6359:296:b0:164:83eb:24d7 with SMTP id ek22csp6776rwb; Wed, 29 Nov 2023 14:02:30 -0800 (PST) X-Google-Smtp-Source: AGHT+IEOV59hpyVCSvgN2QQNZNbDOJDNxnTMX9yEHArl00OXrAQmyygKlAFFLXZI4JdmrjHSS2og X-Received: by 2002:a1f:4ac2:0:b0:495:febd:9187 with SMTP id x185-20020a1f4ac2000000b00495febd9187mr16341779vka.0.1701295349915; Wed, 29 Nov 2023 14:02:29 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1701295349; cv=pass; d=google.com; s=arc-20160816; b=N9r+s7ySSN3MkPsBfb063lWibdz274bUSCFl9D6stWf5wcQyqOrsBaTbT9sRQDAFuC Dg/+59pbncRYyWyCWF05w1TmQD80n0HziRH753Bu6H+QUNDEMyjAIy8G/lIwb3sZXxtY 05jfhofN9njlN7xwheqWET9BRIp6AmAo89bh8adc3HAKuWOZBzdm5l4IZZT3Ama3sL8l Xjc2BxKX/TT2Sjw0GLEPZEBXK15AnCCxr8jTGwT5jTjIV9Ke2ksw+NzwZcobA4Kbhv5V 10zbMPUDyxv+NA+yAGs3zOE7MGklALez94DxMB+4aMgEgpoHMA9fmXgMKiTT5/EJgZ89 9QHA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-disposition:user-agent :in-reply-to:mime-version:references:message-id:subject:cc:to:from :date:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=rR2rAgMNNCm8+A67zahcmidi5WG/L6jscN5FQA7g/7o=; fh=muAvbYaA/AqL9C/xYgVo37JiPefYaM6qV6H1OWr16pw=; b=yyf6p3XpLC7/jcYuEFdjSH2NViCtlJYyq0TBLM7y0293a39p7yOGJyrByr+6DRA8Za 3fzS9lvUOBZ6WpD7f1xoyunwcmdZLrHLEMV8DBjpx16zxriUeC3i3TO8CxCSZHrD4sfC ullgHDez9Zp56VKQDCPGKqQE8ujQcq5lesT7DTgDxTugsT8X+rcsZ4rWRCNAjQxr35Gd G44FxJf72pnzgW25ZuPa11H7WcVBC5ufkdAWKyZ8MwlgWhbg4FZ2R9NFZJe6nb2i5Esk 5iKwTX8ybb2JA0NlRBNqrXEchJKKRtNPJP4yzSZkPbVBF1Rjhv7t/Q1eCz3nu1s/1GwK pCDA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="GeZY/gGQ"; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id l125-20020a1fd483000000b004b030667b3dsi4590620vkg.192.2023.11.29.14.02.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 14:02:29 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b="GeZY/gGQ"; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5E5F13829BDF for ; Wed, 29 Nov 2023 22:02:13 +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 C0359382DC5E for ; Wed, 29 Nov 2023 22:01:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org C0359382DC5E 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 C0359382DC5E 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=1701295309; cv=none; b=GV91jD0vvL/vPnp2fDQR3gGfTqV0y66jnsujtceEZcXICyPriczM9uwb8FAnd+t/ncBfr98JWh/dhtgsPSCdudf6cgUMeR5/yzsyeOs01E58i1uiSWXdDBLkQP8apO0uPyYRZjbpOknZLns5GOofYxCUdRV79g0qhIxA4I95pgM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701295309; c=relaxed/simple; bh=cN2plkPMZYSL4FGGRTfL7KE2cgn3YoD2phjt7eBkU8c=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=rI0doOqKhM/7rH96ytkBnyxON3G4gB717Ke1K9SJb/N3CZE4+DqyzsSEEzqPTP1/B8bGaH0+Q1cgmxNoFLkxm4h43IPyPdNzmso2qJHIhTQ9Mqtp1E/JJ6wvRv4MrOP23t+1PMKhf+m6InbYI653QXhJ9qsq2EkSnOgItfev/cg= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1701295306; 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=rR2rAgMNNCm8+A67zahcmidi5WG/L6jscN5FQA7g/7o=; b=GeZY/gGQp09o5EvbUnHVR8JT3L3AqsfEQmWxez4BqZQDfg9j3thfzH8VbrS0sb3KRg7YMv 4MSvHTtcWUE8Czrbk1lwkk/a2LooM6Gdjzc70DclX+4wKkrx0IWw7TTXieVuzCJ2xGKneR fVX2ysL8M85wXWQBJn1NhFoho8mO1FY= Received: from mail-qv1-f72.google.com (mail-qv1-f72.google.com [209.85.219.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-349-Uo230hWiNHWtNttwrMhyOA-1; Wed, 29 Nov 2023 17:01:43 -0500 X-MC-Unique: Uo230hWiNHWtNttwrMhyOA-1 Received: by mail-qv1-f72.google.com with SMTP id 6a1803df08f44-67a238351b7so3030836d6.2 for ; Wed, 29 Nov 2023 14:01:43 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701295303; x=1701900103; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rR2rAgMNNCm8+A67zahcmidi5WG/L6jscN5FQA7g/7o=; b=lsrN9aZWDK6XJ/Ld+tvuE//XVOEWnnjbfo41U5WpFk2jfdT/m/iNrE0nVJprfy9X0c pq27ToJed0HuHR9MK6E9a2jSTu4DPfEXHOAxJ4zlO9UBOMhBVgrviqxpmvIKh+avr68E RoRL5LvEYeWOJ58RK0DLrt+KFA4J3HdRQcWljOtOXpI3cRR7htC7kr8AZ4wPFsgoxT0W TyGRhqO+4CoAttGoPHYiy2+pJRe7CATGhJe7vicZY7zCcM2Se0gx023Vs9YBqayVlOD2 Wt7QrFJ32b7ApEQ40XDFepXOHf7FcWl4QSpfqEc5YjFEKSyoIvky5r4uH0zmc0P4FtU3 zz7w== X-Gm-Message-State: AOJu0Ywzu+PK/49FeYgSdqHL9dxjzVQKN8M/tptoO7ew0nHGawvpwCXN wNvEZasbO7V1SIQ+A3gTl/SqDXMnW4D7S4O8oekptrCFsGKY3dYN823dSpmYq1MDp4Lu1l0Exuv IKOO6szmYVmMJQuCv2w== X-Received: by 2002:a0c:cd83:0:b0:67a:4dea:ffeb with SMTP id v3-20020a0ccd83000000b0067a4deaffebmr8778982qvm.16.1701295302734; Wed, 29 Nov 2023 14:01:42 -0800 (PST) X-Received: by 2002:a0c:cd83:0:b0:67a:4dea:ffeb with SMTP id v3-20020a0ccd83000000b0067a4deaffebmr8778951qvm.16.1701295302197; Wed, 29 Nov 2023 14:01:42 -0800 (PST) Received: from redhat.com (2603-7000-9500-34a5-0000-0000-0000-1db4.res6.spectrum.com. [2603:7000:9500:34a5::1db4]) by smtp.gmail.com with ESMTPSA id s7-20020a0cf647000000b0067a4396f9cdsm3381858qvm.8.2023.11.29.14.01.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 14:01:41 -0800 (PST) Date: Wed, 29 Nov 2023 17:01:40 -0500 From: Marek Polacek To: Jason Merrill Cc: Patrick Palka , GCC Patches Subject: [PATCH v2] c++: wrong ambiguity in accessing static field [PR112744] Message-ID: References: <20231129154512.428173-1-polacek@redhat.com> MIME-Version: 1.0 In-Reply-To: User-Agent: Mutt/2.2.9 (2022-11-12) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, 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+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783913798143629542 X-GMAIL-MSGID: 1783937472839636876 On Wed, Nov 29, 2023 at 03:28:44PM -0500, Jason Merrill wrote: > On 11/29/23 12:43, Marek Polacek wrote: > > On Wed, Nov 29, 2023 at 12:23:46PM -0500, Patrick Palka wrote: > > > On Wed, 29 Nov 2023, Marek Polacek wrote: > > > > > > > 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 > > > > > > > > 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; > > > > > > I wonder if we want to return ba_check_bit instead of ba_any so that we > > > still check access of the selected base? > > > > That would certainly make sense to me. I didn't do that because > > I'd not seen ba_check_bit being used except as part of ba_check, > > but that may not mean much. > > > > So either I can tweak the lambda to return ba_check_bit rather > > than ba_any or use ba_check_bit unconditionally. Any opinions on that? > > The relevant passage seems to be > https://eel.is/c++draft/class.access.base#6 > after DR 52, which seems to have clarified that the pointer conversion only > applies to non-static members. > > > > struct A { constexpr static int a = 0; }; > > > struct D : private A {}; > > > > > > void f() { > > > D{}.A::a; // #1 GCC (and Clang) currently rejects > > > } > > I see that MSVC also rejects it, while EDG accepts. > > https://eel.is/c++draft/class.access.base#5.1 seems to say that a is > accessible when named in A. > > https://eel.is/c++draft/expr.ref#7 also only constrains references to > non-static members. > > But first we need to look up A in D, and A's injected-class-name looked up > as a member of D is not accessible; it's private, and f() is not a friend, > and we correctly complain about that. > > If we avoid the lookup of A in D with > > D{}.::A::a; > > clang accepts it, which is consistent with accepting the template version, > and seems correct. > > So, I think ba_any is what we want here. Wow, that is not intuitive (to me at least). So I had it right but only by accident. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? -- >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. The rationale for using ba_any is explained at . 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. * g++.dg/lookup/scoped14.C: New test. * g++.dg/lookup/scoped15.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 ++++++++++++++ gcc/testsuite/g++.dg/lookup/scoped14.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/lookup/scoped15.C | 20 ++++++++++++++++++++ 6 files changed, 94 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 create mode 100644 gcc/testsuite/g++.dg/lookup/scoped14.C create mode 100644 gcc/testsuite/g++.dg/lookup/scoped15.C base-commit: 220fe41fd4085e91a49e62dd815628ec4883a4ea diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc index 0839d0a4167..bf8ffaa7e75 100644 --- a/gcc/cp/typeck.cc +++ b/gcc/cp/typeck.cc @@ -3467,7 +3467,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; @@ -3484,9 +3484,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 || shared_member_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." } +} diff --git a/gcc/testsuite/g++.dg/lookup/scoped14.C b/gcc/testsuite/g++.dg/lookup/scoped14.C new file mode 100644 index 00000000000..141aa0d2b1a --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/scoped14.C @@ -0,0 +1,14 @@ +// PR c++/112744 +// { dg-do compile { target c++11 } } + +struct A { int a = 0; }; +struct B : A {}; +struct C : A {}; +struct D : B, C {}; + +int main() +{ + D d; + (void) d.a; // { dg-error "request for member .a. is ambiguous" } + (void) d.A::a; // { dg-error ".A. is an ambiguous base of .D." } +} diff --git a/gcc/testsuite/g++.dg/lookup/scoped15.C b/gcc/testsuite/g++.dg/lookup/scoped15.C new file mode 100644 index 00000000000..d450a41a617 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/scoped15.C @@ -0,0 +1,20 @@ +// PR c++/112744 +// { dg-do compile { target c++11 } } + +struct A { constexpr static int a = 0; }; +struct D : private A {}; + +// See +// for rationale. + +void f() { + D{}.A::a; // { dg-error "inaccessible" } + D{}.::A::a; +} + +template +void g() { + D{}.T::a; +} + +template void g();