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.129.124]) by sourceware.org (Postfix) with ESMTPS id 4EF9D3858D20 for ; Fri, 20 Oct 2023 16:01:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 4EF9D3858D20 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 4EF9D3858D20 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=1697817701; cv=none; b=vw80eNqeZDSKhJWB/NdQz+omWIojrpHwMrIOCTIpLsChE0QKwhFBiqah8Lk/iY6dcvy20u0VvZPTDJyv5s8yLcsMNJ7WMN3P4+5+T+UThueUaJsoSpKuM7qnrK0WCiXoUq0YsY3zgMDfccyjZySY4jmt6afc4TdZGXH0F2YV3YM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697817701; c=relaxed/simple; bh=ZQIbuM2vdOr9q0Klug0s5Ifxh8qS69Hs9k2yhlW/eJ0=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=HO+1z92YXShxLqfoKS4NXf12jkE/AFtccBvGAnkxEjpEXlLvzB8xbjRigoG00/UvIXvMZr20mCIbz169WuEzN92OT4hMHjZj29YaRQHi+Qm10ps8dpoj7PYeJj2BdyMNoHWw9KPMFpPLaTe37tf+lDYL6i6Dzi6Y7xIC7Pa02uI= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1697817698; 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: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lCZMmV0v4Hd/v1PphFV+o1lNVfXQUoDZxRQnlzmg6MQ=; b=LoM4tmKhaoSKl2OUSMbSf1CA6LFToF9pUymLG1hFegzEf+U3xVXDJphFNkU/hT7LLA+54t 0MEF1QU7iK96ta0ZNYS8Mm5aWoxtzDHlgR1Wx07+PY4bLgQ2yeq+9OE0tHUt1TTRg8X1Uq YAE7nul0m2urvs9vEEpjw/px5KdjTSs= Received: from mail-qk1-f198.google.com (mail-qk1-f198.google.com [209.85.222.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-47--liRE6duNgKAHevhS6WSRQ-1; Fri, 20 Oct 2023 12:01:35 -0400 X-MC-Unique: -liRE6duNgKAHevhS6WSRQ-1 Received: by mail-qk1-f198.google.com with SMTP id af79cd13be357-778b25af933so10652185a.3 for ; Fri, 20 Oct 2023 09:01:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697817694; x=1698422494; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=lCZMmV0v4Hd/v1PphFV+o1lNVfXQUoDZxRQnlzmg6MQ=; b=BoC0t3rR0u2LMIA7b2dzR4TR/K1HGPE2kPPX9qSusxN/ppwxKpu5vIwQVodrHpriFC 0UzSvOWZFm8XoQyNxQ909pC5ReBp5OGhaO9KQAyhlFl47IiY+PWSe/Tq5ypDFwUZJtZO e/OdXDhHnMVVJG2HWvqioq2JpbAZshYhzCZntJn+B3fAF5BfhnciCS2nV1ikyOmpXsMl kVMvaVZx8CaRLR2/VAEqOgfyiGJzWn4HOAbEg/3ngOau/fyYyYyZUNmgBA3oHEZb7vYc btxcpAHznDX8CVzYeb48CW6/m4tmfbYlWFYnjwXWsA/K+xtCAGE9NAexTBAUd1ui3/oI +8Jw== X-Gm-Message-State: AOJu0Ywb44NPrJoCPtOUPZyRBtKKTdd8iFYGeGTWu5dIB/tNyUcth3tg faMnlbuBi/Fap6cWM6fIaWuVhbW0fjo6GCveapK1N1/DwswaMIXRw/3Dj5Y5THUdJ1BnKdnyY9K JaiIdKfQoXPUwofrrRQ== X-Received: by 2002:a0c:de09:0:b0:66d:1f6f:1645 with SMTP id t9-20020a0cde09000000b0066d1f6f1645mr1839143qvk.27.1697817694404; Fri, 20 Oct 2023 09:01:34 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEJnBM9oaSd7FMkGgcf3YkWADHJqwbT4z6SwMbO2gb9LbybeIos/lXMRhJkfLh9WMmotoUHMg== X-Received: by 2002:a0c:de09:0:b0:66d:1f6f:1645 with SMTP id t9-20020a0cde09000000b0066d1f6f1645mr1839115qvk.27.1697817693877; Fri, 20 Oct 2023 09:01:33 -0700 (PDT) Received: from [192.168.1.108] (130-44-146-16.s12558.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.146.16]) by smtp.gmail.com with ESMTPSA id d14-20020a0cfe8e000000b0065896b9fb15sm777947qvs.29.2023.10.20.09.01.32 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 20 Oct 2023 09:01:32 -0700 (PDT) Message-ID: <635f5d6d-2807-4dff-8a37-73d323d6ea97@redhat.com> Date: Fri, 20 Oct 2023 12:01:32 -0400 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3 1/2] c++: Initial support for P0847R7 (Deducing This) [PR102609] To: waffl3x Cc: "gcc-patches@gcc.gnu.org" References: <0cc5b21d-4b27-4964-bec3-544c86307c74@redhat.com> <1fdadb6b-e4ca-40c1-bb1c-43a0f42826ba@redhat.com> From: Jason Merrill In-Reply-To: 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=-6.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 10/20/23 00:34, waffl3x wrote: >>> >>> Based on what you've said, I assume that OFFSET_REF handles static >>> member functions that are overloaded. But as I've said this seems to >>> contradict the comments I'm reading, so I'm not sure that I'm >>> understanding you correctly. >> >> >> That's right. For instance, >> >> struct A { >> static void g(); >> static void g(int); >> }; >> >> void (*p)(int) = &A::g; // cp_build_addr_expr_1 gets an OFFSET_REF >> >>>>> I think we need the OFFSET_REF for an explicit-object member function >>>>> because it expresses that the code satisfies the requirement "If the >>>>> operand names an explicit object member function, the operand shall be a >>>>> qualified-id." >>> >>> I do agree here, but it does reinforce that OFFSET_REF is no longer >>> just for members represented by pointer to member type. So that might >>> be something to take into consideration. >> >> >> An OFFSET_REF that isn't type_unknown_p, agreed. >> >>>>> It might simplify things to remove the optimization in build_offset_ref >>>>> so we get an OFFSET_REF even for a single static member function, and >>>>> add support for that to cp_build_addr_expr_1. >>> >>> I don't think this should be necessary, the "right thing" should just >>> be done for explicit-object member functions. With all the stuff going >>> on here that I missed I'm starting to wonder how function overloads >>> ever worked at all in my patch. On the other hand though, this >>> optimization probably could be documented better, but I very well might >>> have missed it even if it were. >>> >>> Hell, maybe it needs a greater redesign altogether, it seems strange to >>> me to bundle overload information in with a construct for a specific >>> expression. (Assuming that's whats happening of course, I still don't >>> fully understand it.) It's not like this has rules unique to it for how >>> overload resolution is decided, right? Initializing a param/variable of >>> pointer to function type with an overloaded function resolves that with >>> similar rules, I think? Maybe it is a little different now that I write >>> it out loud. >>> >>> I wasn't going to finish my musings about that, but it made me realize >>> that it might not actually be correct for address of explicit-object >>> member functions to be wrapped by OFFSET_REF. I mean surely it's fine >>> because based on what you've said static member functions are also >>> wrapped by OFFSET_REF, so it's likely fully implemented, especially >>> considering things worked before. But now that there are 2 different >>> varieties of class members that the address of them can be taken, it >>> might make sense to split things up a bit? Then again, why were static >>> member functions ever handled the same way? Taking the address of other >>> static members isn't handled in the same way here is it? >> >> >> Functions are different because of overloading; in general we can't >> decide what an expression that names a function actually means until we >> have enough context to decide which function, exactly. So we represent >> the id-expression largely as lookup+syntax until overload resolution >> turns it into a specific function. The type_unknown_p check earlier in >> cp_build_addr_expr_1 is for that case. > > Yeah this all makes sense, but that's why I was confused by the > following documentation from cp-tree.def. > > ``` > /* An OFFSET_REF is used in two situations: > > 1. An expression of the form `A::m' where `A' is a class and `m' is > a non-static member. In this case, operand 0 will be a TYPE > (corresponding to `A') and operand 1 will be a FIELD_DECL, > BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m'). > > The expression is a pointer-to-member if its address is taken, > but simply denotes a member of the object if its address is not > taken. > ``` Yeah, I'll adjust that statement to be more conditional. Is this clearer? 1. An expression of the form `A::m' where `A' is a class and `m' is a non-static member or an overload set. In this case, operand 0 will be a TYPE (corresponding to `A') and operand 1 will be a FIELD_DECL, BASELINK, or TEMPLATE_ID_EXPR (corresponding to `m'). The expression is a pointer-to-member if its address is taken (and if, after any overload resolution, 'm' does not designate a static or explicit object member function). It simply denotes a member of the object if its address is not taken. >> An OFFSET_REF that isn't type_unknown_p, agreed. > But I suppose that's what this might have been referring to. > > So is that the case then? OFFSET_REF might be for a regular address of > member expression unless it's type_unknown_p? If it's type_unknown_p we don't know which member it is, so we don't know whether taking its address gives a PMF or a regular pointer. If it's not type_unknown_p, we know which member it is, and we currently skip building it at all for static members, so taking its address always gives a pointer to member. explicit object member functions will make that assumption no longer valid. >> An id-expression that names a single non-template function >> (!really_overloaded_fn) is handled somewhat differently, as we don't >> need to defer everything. But that means various special-case code. >> >> Currently build_offset_ref special-cases &A::f for a single static >> member function, but we can't use the same special case for single >> explicit object member functions because we need to distinguish between >> &A::f and &f somehow to check the requirement I quoted above. So it >> seems to me we'll need to add support for single explicit object member >> functions in the OFFSET_REF handling in cp_build_addr_expr_1. And I >> thought if we're doing that, perhaps we want to move the single static >> handling over there as well, but that's not necessary. > > I'm done for today but it does seem like that special case is what is > causing my crash. I found that it only jumps into the section that it > crashes in when there are no overloads. I'm kinda close to fixing it > probably but I've spent too long on it for today, it's melting together. > >> Currently build_offset_ref special-cases &A::f for a single static >> member function, but we can't use the same special case for single >> explicit object member functions because we need to distinguish between >> &A::f and &f somehow to check the requirement I quoted above. > > I don't understand what this means exactly, under what circumstances > would &f find the member function. Oh, I guess while in the body of > it's class, I hadn't considered that. Is that what you're referring to? Right: struct A { void g(this A&); A() { &A::g; // ok &g; // same error as for an implicit object member function } }; > Well either way, I'm going to pick back up here tomorrow and see if I > can finish figuring out exactly whats causing the problems. I'm pretty > certain it's the special case that causes it, I'm just not sure what > part exactly is causing the difference, and whether there aren't more > hiding issues. But for now I need to get some rest. Thanks for the > detailed responses, they helped a lot, this part of the code has been > particularly difficult to figure out. You're welcome, thanks for your interest. Jason