On Thu, Sep 4, 2025 at 10:27 AM Jonathan Wakely <jwak...@redhat.com> wrote: > > On Thu, 4 Sept 2025 at 08:26, Richard Biener <rguent...@suse.de> wrote: > > > > On Wed, 3 Sep 2025, Jakub Jelinek wrote: > > > > > On Wed, Sep 03, 2025 at 06:41:08PM +0200, Richard Biener wrote: > > > > > I'd be worried about C++23 deducing this, but e.g. > > > > > struct S; > > > > > extern S t; > > > > > struct S > > > > > { > > > > > void foo (this S *p, int x); > > > > > int s; > > > > > }; > > > > > void S::foo (this S *p, int x) > > > > > { > > > > > p->s += x; > > > > > p = &t; > > > > > p->s += x; > > > > > } > > > > > > > > Huh, you can assign to the ‚this‘ parameter? I’ve read it can be a > > > > non-pointer. But assigning to it makes the non-SSA match broken. > > > > What’s the use of such assignment? > > > > Is p = nullptr valid? Or delete p;? > > > > > > Clearly both g++ and clang++ compile this (but I'm then getting errors > > > when trying to call it as t.foo (42); or ptr->foo (42)). > > > Guess normally for deducing this the argument is this S &p instead and > > > references can't be changed. But normal this in methods is actually > > > a pointer and keyword such that one can't change it either. > > > Or in some tests it is this S and so passed by value. That then can > > > be called as t.foo (42). > > > > I've skimmed through the paper for the feature and found no wording > > constraining assignment but also no example doing it ... > > > > We also accept > > > > struct B {}; > > struct S > > { > > void foo (this B *p, int x); > > int s; > > }; > > extern S t; > > void S::foo (this B *p, int x) > > { > > } > > > > though I'm not sure you'd ever be able to call this? > > You can if S has an implicit conversion to B* > > struct B {}; > struct S > { > void foo (this B *p, int x); > int s; > operator B*() { return &b; } > B b; > }; > extern S t; > void S::foo (this B *p, int x) > { > } > > int main() > { > S s; > s.foo(1); > } > > > > > int main() { B b; b.foo (1); } > > > > is rejected obviously, so is b.S::foo (1). I think this would > > warrant a diagnostic at least. Maybe there's a trick to make > > name lookup succeed though? > > > > That said, the invocation syntax suggests that the 'this' object > > must be valid, the question is whether it's constrained by the > > type of the formal argument only or by the class type > > (TYPE_METHOD_BASETYPE if it were a method). > > Yes, it is. You can't call Foo::mem on an object that isn't a Foo or a > type derived from Foo. > > > That said, assigning > > to the this parameter adds a dataflow problem, easy for the SSA > > side but impossible to resolve while in GENERIC - this makes > > it necessary to perform EH pruning during SSA rewrite. > > > > That said, it's odd that the proposed "just alternative syntax" > > produces a non-method type and also allows assigning to 'this'. > > It's not 'this' though! It's not a method, it's a static member > function, so there is no implicit 'this' pointer. The parameter is > declared as 'this S' or 'this B' but that's just a token that says > the function uses the new syntax, it doesn't mean that the parameter > *is* the 'this' pointer.
Hmm, but the paper explicitly says it's _not_ a static member function which to me suggests that the 'this' marked parameter must bind to a valid object (of the declared type then, I guess). But all these details seem to be absent from the paper ... So I hope struct S { void foo (this S *); int i; }; ((S *)0)->foo (); char c; ((S *)&c)->foo (); are both invalid, aka invoking UB. Richard. > > > But well, C++ mess, as usual :/ > > > > Richard. >