From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 A81673834E41 for ; Thu, 26 May 2022 20:39:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A81673834E41 Received: from mail-qt1-f198.google.com (mail-qt1-f198.google.com [209.85.160.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-554-THbbC_DKNxe_w3JmsQvOEg-1; Thu, 26 May 2022 16:39:21 -0400 X-MC-Unique: THbbC_DKNxe_w3JmsQvOEg-1 Received: by mail-qt1-f198.google.com with SMTP id u2-20020ac80502000000b002f94701339eso2713001qtg.13 for ; Thu, 26 May 2022 13:39:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=/nXkEFnGjDrTZat1sJNYnmJKzcnjQLZ12kmFrny9SqY=; b=okv46DyjY910POx4CKTC7AHr1tT2OGNlTVEhYrBiGFCalJQOvyI1GFRRXieFZ8s3s2 vajkd2OuVHeXoAHQGVOZdwr4sjIUxm3gZsx3K+yGhjsIoIksIeU+hKYNvmX8zyiPjB+s +t9BBOfNeQlQf/TctlSip8nX4YBRsw4l8c9Mm/Wiyll7ca9HkIulRvqBvCNuQgg7ID5q 6M/9oEdgTMdUh5SKBiPdA0b+HAKFvqeEfO0LTz3ggLxRR4wfVYCjV4+hn47DxWL2nTa8 l9Psjv9ostEf0JRoZr1lSjhgwxcTGOAqeaYyY1Ku8pUOALintkOjTvi6sxMSkmavqvGH 9aiw== X-Gm-Message-State: AOAM533dGwAKO2vvHMCjBRKGeXC048Wo/Qwv0IYwTdmXxeKp71JJVMyT qDMYKlC9P7oH0USdphiLnUAyDPby5EKDr0J/MvUGwurdfono7R72fAUWAsxtwm/u2LqUeP7IGys tBI/nMK6TDjBCSfeamQ== X-Received: by 2002:a05:622a:1115:b0:2f3:bd60:a33b with SMTP id e21-20020a05622a111500b002f3bd60a33bmr30315933qty.292.1653597560270; Thu, 26 May 2022 13:39:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwmtSghP+QBHZ0EIyA/1sVVtvxireFYt0caWMw9HIK3Boljgy0vx+a3t40ic1jmsVo3eIHnIA== X-Received: by 2002:a05:622a:1115:b0:2f3:bd60:a33b with SMTP id e21-20020a05622a111500b002f3bd60a33bmr30315918qty.292.1653597559920; Thu, 26 May 2022 13:39:19 -0700 (PDT) Received: from [192.168.1.100] (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id bq15-20020a05620a468f00b006a5a07bb868sm1839662qkb.119.2022.05.26.13.39.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 26 May 2022 13:39:18 -0700 (PDT) Message-ID: <34d2cabf-523c-098d-633d-8e3d7619f8b1@redhat.com> Date: Thu, 26 May 2022 16:39:17 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.9.1 Subject: Re: [PATCH] c++: cv-quals of dummy obj for non-dep memfn call [PR105637] To: Patrick Palka Cc: gcc-patches@gcc.gnu.org References: <20220526183450.2331967-1-ppalka@redhat.com> <527705e5-b69c-f1bd-f531-6bb43e10713b@idea> From: Jason Merrill In-Reply-To: <527705e5-b69c-f1bd-f531-6bb43e10713b@idea> X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit 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, NICE_REPLY_A, RCVD_IN_DNSWL_NONE, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 May 2022 20:39:26 -0000 On 5/26/22 14:57, Patrick Palka wrote: > On Thu, 26 May 2022, Patrick Palka wrote: > >> Here we expect the calls to BaseClass::baseDevice resolve to the second, >> third and fourth overloads respectively in light of the cv-qualifiers >> of 'this' in each case. But ever since r12-6075-g2decd2cabe5a4f, the >> calls incorrectly resolve to the first overload at instantiation time. >> >> This happens because the calls to BaseClass::baseDevice are all deemed >> non-dependent (ever since r7-755-g23cb72663051cd made us ignore the >> dependentness of 'this' when considering the dependence of a non-static >> memfn call), hence we end up checking the call ahead of time, using as >> the object argument a dummy object of type BaseClass. Since this object >> argument is cv-unqualified, the calls incoherently resolve to the first >> overload of baseDevice. Before r12-6075, this incorrect result would >> just get silently discarded and we'd end up redoing OR at instantiation >> time using 'this' as the object argument. But after r12-6075, we now >> reuse this incorrect result at instantiation time. >> >> This patch fixes this by making finish_call_expr request from >> maybe_dummy_object a cv-qualified object consistent with the cv-quals of >> 'this'. That way, ahead of time OR using a dummy object will give us >> the right answer and we could safely reuse it at instantiation time. >> >> NB: r7-755 is also the cause of the related issue PR105742. Not sure >> if there's a fix that could resolve both PRs at once.. >> >> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK >> for trunk/12? >> >> PR c++/105637 >> >> gcc/cp/ChangeLog: >> >> * semantics.cc (finish_call_expr): Pass a cv-qualified object >> type to maybe_dummy_object that is consistent with the >> cv-qualifiers of 'this' if available. >> >> gcc/testsuite/ChangeLog: >> >> * g++.dg/template/non-dependent23.C: New test. >> --- >> gcc/cp/semantics.cc | 15 ++++++++--- >> .../g++.dg/template/non-dependent23.C | 25 +++++++++++++++++++ >> 2 files changed, 37 insertions(+), 3 deletions(-) >> create mode 100644 gcc/testsuite/g++.dg/template/non-dependent23.C >> >> diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc >> index cd7a2818feb..1d9348c6cf1 100644 >> --- a/gcc/cp/semantics.cc >> +++ b/gcc/cp/semantics.cc >> @@ -2802,16 +2802,25 @@ finish_call_expr (tree fn, vec **args, bool disallow_virtual, >> [class.access.base] says that we need to convert 'this' to B* as >> part of the access, so we pass 'B' to maybe_dummy_object. */ >> >> + tree object_type = BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)); >> if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (get_first_fn (fn))) >> { >> /* A constructor call always uses a dummy object. (This constructor >> call which has the form A::A () is actually invalid and we are >> going to reject it later in build_new_method_call.) */ >> - object = build_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn))); >> + object = build_dummy_object (object_type); >> } >> else >> - object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)), >> - NULL); >> + { >> + if (current_class_ref) >> + { >> + /* Make sure that if maybe_dummy_object gives us a dummy object, >> + it'll have the same cv-quals as '*this'. */ >> + int quals = cp_type_quals (TREE_TYPE (current_class_ref)); >> + object_type = cp_build_qualified_type (object_type, quals); >> + } >> + object = maybe_dummy_object (object_type, NULL); >> + } >> >> result = build_new_method_call (object, fn, args, NULL_TREE, >> (disallow_virtual > > Drat, this fix doesn't interact well with 'this'-capturing lambdas: > > struct BaseClass { > void baseDevice(); // #1 > void baseDevice() const = delete; // #2 > }; > > template > struct TopClass : T { > void failsToCompile() { > [this] { BaseClass::baseDevice(); }(); > } > }; > > template struct TopClass; > > Here after the fix, we'd incorrectly select the const #2 overload at > template definition time because current_class_ref is the const 'this' > for the lambda rather than the non-const 'this' for TopClass.. I suppose > we need something like current_nonlambda_class_type for getting at the > innermost non-lambda 'this'? Do you want maybe_resolve_dummy (ob, false)? >> diff --git a/gcc/testsuite/g++.dg/template/non-dependent23.C b/gcc/testsuite/g++.dg/template/non-dependent23.C >> new file mode 100644 >> index 00000000000..ef95c591b75 >> --- /dev/null >> +++ b/gcc/testsuite/g++.dg/template/non-dependent23.C >> @@ -0,0 +1,25 @@ >> +// PR c++/105637 >> + >> +struct BaseClass { >> + void baseDevice(); // #1 >> + void baseDevice() const; // #2 >> + void baseDevice() volatile; // #3 >> + void baseDevice() const volatile; // #4 >> +}; >> + >> +template >> +struct TopClass : T { >> + void failsToCompile() const { >> + BaseClass::baseDevice(); // should select #2, not #1 >> + } >> + >> + void failsToCompile() volatile { >> + BaseClass::baseDevice(); // should select #3, not #1 >> + } >> + >> + void failsToCompile() const volatile { >> + BaseClass::baseDevice(); // should select #4, not #1 >> + } >> +}; >> + >> +template struct TopClass; >> -- >> 2.36.1.182.g6afdb07b7b >> >> >