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.

> But well, C++ mess, as usual :/
>
> Richard.

Reply via email to