public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/102609] New: [C++23] P0847R7 - Deducing this
@ 2021-10-05 15:56 mpolacek at gcc dot gnu.org
  2021-11-28 11:33 ` [Bug c++/102609] " pinskia at gcc dot gnu.org
                   ` (28 more replies)
  0 siblings, 29 replies; 30+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2021-10-05 15:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

            Bug ID: 102609
           Summary: [C++23] P0847R7 - Deducing this
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mpolacek at gcc dot gnu.org
            Blocks: 98940
  Target Milestone: ---

See https://wg21.link/p0847r7


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98940
[Bug 98940] Implement C++23 language features

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
@ 2021-11-28 11:33 ` pinskia at gcc dot gnu.org
  2023-06-12 23:37 ` mpolacek at gcc dot gnu.org
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-11-28 11:33 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
     Ever confirmed|0                           |1
   Last reconfirmed|                            |2021-11-28

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
  2021-11-28 11:33 ` [Bug c++/102609] " pinskia at gcc dot gnu.org
@ 2023-06-12 23:37 ` mpolacek at gcc dot gnu.org
  2023-08-16 18:29 ` waffl3x at protonmail dot com
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2023-06-12 23:37 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Related: https://cplusplus.github.io/CWG/issues/2653.html

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
  2021-11-28 11:33 ` [Bug c++/102609] " pinskia at gcc dot gnu.org
  2023-06-12 23:37 ` mpolacek at gcc dot gnu.org
@ 2023-08-16 18:29 ` waffl3x at protonmail dot com
  2023-08-16 18:48 ` gasper.azman at gmail dot com
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-08-16 18:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #3 from waffl3x <waffl3x at protonmail dot com> ---
I have some elements working so far, I opted to implement parsing for `this` in
cp_parser_parameter_declaration instead of in cp_parser_decl_specifier_seq
because I didn't want to add another member to cp_decl_specifier_seq, but I
ended up doing it anyway in the end. The `this` clause isn't a specifier so I
thought including it in the same function for parsing decl-specifier-seq would
be odd, but I ended up needing to put code to skip the first `this` token into
cp_parser_decl_specifier_seq so I don't know if that was the right decision in
the end. Ultimately I would like to refactor attribute parsing into another
function instead of having it be a part of cp_parser_decl_specifier_seq, but
I'm not going to do that while implementing "deducing this."

I'm uncertain of where to put the error checking, right now it is in
grokdeclarator. Setting the "explicit object function flag" is also in
grokdeclarator at the moment as I wanted to avoid adding more parameters to
functions. I'm pretty unhappy with how the code is organized, so if anyone has
any opinions on where certain things should be done, please share them.

Right now, parsing the `this` clause works, and errors are reported when it is
used other than in the first parameter, with an altered diagnostic when it is
used multiple times. There is also a diagnostic when `this` is used in a
function type declaration.

Input would be appreciated, thanks.

(In reply to Marek Polacek from comment #2)
> Related: https://cplusplus.github.io/CWG/issues/2653.html

I don't currently implement this, but I was going to, however I am unsure on
whether it's been merged into the standard, I guess "Status: C++23" means that
it was, yeah?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (2 preceding siblings ...)
  2023-08-16 18:29 ` waffl3x at protonmail dot com
@ 2023-08-16 18:48 ` gasper.azman at gmail dot com
  2023-08-16 18:50 ` gasper.azman at gmail dot com
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: gasper.azman at gmail dot com @ 2023-08-16 18:48 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #4 from Gašper Ažman <gasper.azman at gmail dot com> ---
As one of the authors, I can assure you you never need to implement this for
c++23.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (3 preceding siblings ...)
  2023-08-16 18:48 ` gasper.azman at gmail dot com
@ 2023-08-16 18:50 ` gasper.azman at gmail dot com
  2023-08-16 21:58 ` waffl3x at protonmail dot com
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: gasper.azman at gmail dot com @ 2023-08-16 18:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #5 from Gašper Ažman <gasper.azman at gmail dot com> ---
And of course by "this" I meant support for a default argument on the explicit
object parameter.

We might add it back in the future if we find a usecase.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (4 preceding siblings ...)
  2023-08-16 18:50 ` gasper.azman at gmail dot com
@ 2023-08-16 21:58 ` waffl3x at protonmail dot com
  2023-08-19  8:44 ` waffl3x at protonmail dot com
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-08-16 21:58 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #6 from waffl3x <waffl3x at protonmail dot com> ---
I've noticed the standard does call `this` a specifier, I will perhaps rework
the code to just do parsing in cp_decl_specifier_seq.

(In reply to Gašper Ažman from comment #5)
> And of course by "this" I meant support for a default argument on the
> explicit object parameter.
> 
> We might add it back in the future if we find a usecase.

Great, I will just forbid it then, I can't think of a compelling reason to make
it a warning even if it should be benign.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (5 preceding siblings ...)
  2023-08-16 21:58 ` waffl3x at protonmail dot com
@ 2023-08-19  8:44 ` waffl3x at protonmail dot com
  2023-08-19  9:38 ` redi at gcc dot gnu.org
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-08-19  8:44 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #7 from waffl3x <waffl3x at protonmail dot com> ---
struct S {
    int f(this S*) {
        return 5;
    }
};

int main()
{
    S s{};
    return s.f();
}

Here is my current progress, this code works. I have a good feeling that the
rest is going to be easy. Except for deduction maybe, but I have a minor hunch
that it might -just work- without any extra tinkering after everything else has
been implemented.
Also yes, I know that `int f(this S*)` is not a valid declaration, I just
didn't have to change any member function call code for it to work this way so
I made it my first goal to implement it this way.

Actually, I guess it's not explicitly invalid is it? I don't recall seeing it
in the pathological cases section of the paper, indeed, I just checked and
there doesn't seem to be mention of it. I believe it should probably be valid
though, not useful if you ask me. Even less so than the other pathological
cases (which I think might actually prove to be useful in some cases.) However,
regardless of my opinion, following the same direction as the original paper, I
imagine it should be allowed. The class would just need an implicit conversion
to pointer, maybe a warning would be in order though?

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (6 preceding siblings ...)
  2023-08-19  8:44 ` waffl3x at protonmail dot com
@ 2023-08-19  9:38 ` redi at gcc dot gnu.org
  2023-08-19  9:43 ` redi at gcc dot gnu.org
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: redi at gcc dot gnu.org @ 2023-08-19  9:38 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #8 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I don't see anything forbidding that declaration, but I think it can only be
called if S& has an implicit conversion to S* because the object parameter is
an lvalue of type S, and so it can only match S* via an implicit conversion.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (7 preceding siblings ...)
  2023-08-19  9:38 ` redi at gcc dot gnu.org
@ 2023-08-19  9:43 ` redi at gcc dot gnu.org
  2023-08-19 16:10 ` gasper.azman at gmail dot com
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: redi at gcc dot gnu.org @ 2023-08-19  9:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
If we're right about that, then I agree that a warning would be useful for
classes that have no such implicit conversion from S to S*.

I think the warning would give a false positive in the case below, so a way to
disable it locally would be needed (e.g. via a diagnostic pragma).

struct S {
  int f(this S*); // warning: explicit object parameter of pointer type can
only match if an implicit conversion to S* exists
};

struct T : S {
  operator T*();
};

T t;
int i = t.f(); // derived class has the required conversion

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (8 preceding siblings ...)
  2023-08-19  9:43 ` redi at gcc dot gnu.org
@ 2023-08-19 16:10 ` gasper.azman at gmail dot com
  2023-08-19 21:24 ` waffl3x at protonmail dot com
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: gasper.azman at gmail dot com @ 2023-08-19 16:10 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #10 from Gašper Ažman <gasper.azman at gmail dot com> ---
Yes, the explicit object parameter always receives the cv-l/r qualified
reference to the object of the call. Implicit conversions are then of
course allowed, same as any other parameter. S* is not that useful as a
type of an explicit object parameter, implicit conversions to pointer to
yourself are probably about as weird as overloading operator&().

Also, don't forget explicit object function bodies and their type behave a
lot more like static functions than member functions.

On Sat, Aug 19, 2023, 10:43 redi at gcc dot gnu.org <
gcc-bugzilla@gcc.gnu.org> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609
>
> --- Comment #9 from Jonathan Wakely <redi at gcc dot gnu.org> ---
> If we're right about that, then I agree that a warning would be useful for
> classes that have no such implicit conversion from S to S*.
>
> I think the warning would give a false positive in the case below, so a
> way to
> disable it locally would be needed (e.g. via a diagnostic pragma).
>
> struct S {
>   int f(this S*); // warning: explicit object parameter of pointer type can
> only match if an implicit conversion to S* exists
> };
>
> struct T : S {
>   operator T*();
> };
>
> T t;
> int i = t.f(); // derived class has the required conversion
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (9 preceding siblings ...)
  2023-08-19 16:10 ` gasper.azman at gmail dot com
@ 2023-08-19 21:24 ` waffl3x at protonmail dot com
  2023-08-20 14:21 ` gasper.azman at gmail dot com
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-08-19 21:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #11 from waffl3x <waffl3x at protonmail dot com> ---
(In reply to Jonathan Wakely from comment #9)
> If we're right about that, then I agree that a warning would be useful for
> classes that have no such implicit conversion from S to S*.
> 
> I think the warning would give a false positive in the case below, so a way
> to disable it locally would be needed (e.g. via a diagnostic pragma).
> 
> struct S {
>   int f(this S*); // warning: explicit object parameter of pointer type can
> only match if an implicit conversion to S* exists
> };
> 
> struct T : S {
>   operator T*();
> };
> 
> T t;
> int i = t.f(); // derived class has the required conversion

I've ran some ideas in my head, no matter what is the decided upon design I
fully agree that all the warnings must be implemented with flags so they can be
suppressed, each independent of the other. I explain the warning I would
propose below, and I will make sure each one is properly documented, especially
since one of them has a clear risk of false positives, as you demonstrated.

(In reply to Gašper Ažman from comment #10)
> S* is not that useful as a
> type of an explicit object parameter, implicit conversions to pointer to
> yourself are probably about as weird as overloading operator&().

The only compelling case I can think of for such a thing would be passing a
pointer type that isn't related by inheritance anyway. That is to say, I'm not
disagreeing with you, I just stopped to think about it and came up with this,
consider the following example.

struct my_function {
    using func_ptr = void(*)(int);
    func_ptr _f;

    void operator()(this func_ptr f, int a) {
        return f(a);
    }

    operator func_ptr() const {
        return _f;
    }
};

I'm mostly just excited to share what I finally thought of as a good example
for an explicit object parameter that is not of a deduced or base type, but
it's never the less a pointer type.
Granted, I think this type of use should also have some sort of warning
available as it is still weird.

I think a warning for declaring an explicit object parameter as a pointer to
base, derived, or deduced type should be in, since a reference is probably the
best choice in that case. Perhaps deduced type shouldn't be included in that
warning, as there are cases that are kind of compelling for having that, one
could trap implicit conversions to any pointer type that way on derived
classes.

To elaborate on what I said above, I still think a warning when using a type
that is not related to the class should be provided. Even given that my example
above presents a legitimate pattern, I think it's use is infrequent enough to
provide an optional warning for this. I question if there's any value in
suppressing the warning when there are legitimate conversions present, as it
would no longer inform the user that they might have done something by mistake.
Essentially, since it's not possible to warn that there are no viable
conversions without false positives occurring, I think the warning should be
present simply because you are doing something weird, not because you are
declaring a function that won't be selected by overload resolution.

Just to reiterate, I fully agree that both warnings should be behind a flag. I
think I would propose that the first (warning for pointer to base, derived, or
deduced type in an explicit object parameter) should be turned on by default,
while the second should be turned off by default.

struct S : B {
    int f0(this B*) {} // warning 1, on by default
    int f1(this S*) {} // warning 1, on by default 
    int f2(this auto*) {} // warning 1, on by default?, separate warning?

    int f3(this int) {} // warning 2, off by default(?)
};

On the other hand, warning 2 could be split into 2 warnings, where one would
warn for a "weird" explicit object parameter, while the other would warn for
uncallable functions due to a lack of implicit conversions.
warning 2: weird explicit object parameter
warning 3: uncallable function (possibly has false positives)

struct S {
    operator int() const {}

    int f0(this int) {} // emits warning 2
    int f1(this some_type) {} // emits warning 2 or 3
};

I imagine my proposed warnings 2 and 3 should be mutually exclusive, but I'm
not sure which should take precedence.

I suppose I've bikeshedded this a bit but I wanted to get my ideas up here
before I start working on things again today.


> Also, don't forget explicit object function bodies and their type behave a
> lot more like static functions than member functions.

Yes, that is one of the next thing's on my list to implement. At the moment
they are still member function pointer types.
My current plan is;
1. Pass reference to object when calling explicit object member functions.
2. Convert the function type of explicit object member functions to regular
function types.
3. Make sure calling explicit object member functions as member functions still
works.
4. finally, implement calling explicit object member functions through a
pointer to function. (Which should hopefully be free to implement.)



A little off topic, but my function pointer wrapper example above got me
thinking about things and I don't have a better place to share them.
The example only really feels good because the implicit conversion is already
fairly natural for the type. What about cases where an implicit conversion
doesn't make sense, but still wants to benefit from such a pattern? I have to
wonder if a solution would be allowing private conversion operators to be
selected when calling an explicit object member function.
I guess that doesn't work properly when calling it through a pointer to the
function though, so surely this would have more issues than it's worth.
I have some other bad ideas on how to facilitate this, but they are far too
cursed to share here, so I will stop stalling and get to work.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (10 preceding siblings ...)
  2023-08-19 21:24 ` waffl3x at protonmail dot com
@ 2023-08-20 14:21 ` gasper.azman at gmail dot com
  2023-08-21  1:24 ` waffl3x at protonmail dot com
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: gasper.azman at gmail dot com @ 2023-08-20 14:21 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #12 from Gašper Ažman <gasper.azman at gmail dot com> ---
Replies to relevant snippets inline.

That was quite a write-up!


> The only compelling case I can think of for such a thing would be passing a
> pointer type that isn't related by inheritance anyway. That is to say, I'm not
> disagreeing with you, I just stopped to think about it and came up with this,
> consider the following example.
>
> struct my_function {
>     using func_ptr = void(*)(int);
>     func_ptr _f;
>
>     void operator()(this func_ptr f, int a) {
>         return f(a);
>     }
>
>     operator func_ptr() const {
>         return _f;
>     }
> };


This case is already covered by surrogate functions:

struct S {
    using fptr = int(*)(int);
    operator fptr() const {
        return +[](int){return 42;};
    }
};

int main() {
    S x;
    x(3); // OK, returns 42
}


https://godbolt.org/z/48Efzdr1q

The conversion operator is a better match in this case, so the
operator() which requires an implicit conversion is not the one
called.

>
> I'm mostly just excited to share what I finally thought of as a good example
> for an explicit object parameter that is not of a deduced or base type, but
> it's never the less a pointer type.

Converting to a pointer-type is not weird; it's converting to pointer
to your own type that is. Any proxy object with a conversion operator
to its underlying will have that if the underlying happens to be a
pointer type. Such a proxy object might well forward methods directly
to the underlying object via a conversion instead of stamping out a
body for each cv-ref qualifier.

> Granted, I think this type of use should also have some sort of warning
> available as it is still weird.

I disagree; conversion to your own type I think is a reasonable
warning (unless you have a conversion operator in the same class)
because it can come with a fixit hint (replace with reference to S
instead). All other types are legit.

> I think a warning for declaring an explicit object parameter as a pointer to
> base, derived, or deduced type should be in, since a reference is probably the
> best choice in that case.

I definitely agree that this warning is reasonable.

> Perhaps deduced type shouldn't be included in that
> warning, as there are cases that are kind of compelling for having that, one
> could trap implicit conversions to any pointer type that way on derived
> classes.

Yeah, deduced is legit, no warning for that one unless we discover
active pathologies.

> To elaborate on what I said above, I still think a warning when using a type
> that is not related to the class should be provided.

Strong disagree, that'll break a lot of code I actually intend to
write. Not stamping out additional template instantiations /  better
ABI by having implicit conversions will, I expect, be quite the common
implementation trick (for instance, any member algorithm on a vector
that doesn't change size can be called on an equivalent span instead
and therefore be passed in registers). This can be an implementation
detail of vector, so that vector and array can share template
instantiations, for instance.

> Even given that my example
> above presents a legitimate pattern, I think it's use is infrequent enough to
> provide an optional warning for this. I question if there's any value in
> suppressing the warning when there are legitimate conversions present, as it
> would no longer inform the user that they might have done something by mistake.

I think my ruminations above give a good example of why such false
positives should definitely be expected in well-behaved code.

> Essentially, since it's not possible to warn that there are no viable
> conversions without false positives occurring, I think the warning should be
> present simply because you are doing something weird, not because you are
> declaring a function that won't be selected by overload resolution.

Yes, but you can get a pointer to it and call it directly. Might be a
useful way to pass overload sets.

> Just to reiterate, I fully agree that both warnings should be behind a flag. I
> think I would propose that the first (warning for pointer to base, derived, or
> deduced type in an explicit object parameter) should be turned on by default,
> while the second should be turned off by default.

I'm not sure the second one should even exist, as it's bound to be
even more annoying than -Wshadow.

>
> struct S : B {
>     int f0(this B*) {} // warning 1, on by default
>     int f1(this S*) {} // warning 1, on by default
>     int f2(this auto*) {} // warning 1, on by default?, separate warning?
>
>     int f3(this int) {} // warning 2, off by default(?)
> };

I say no warning on f2. S could be a CRTP-sans-CRTP mixin that expect
that conversion to exist.

>
> On the other hand, warning 2 could be split into 2 warnings, where one would
> warn for a "weird" explicit object parameter, while the other would warn for
> uncallable functions due to a lack of implicit conversions.
> warning 2: weird explicit object parameter
> warning 3: uncallable function (possibly has false positives)

I expect f3 to be a very common thing.

>
> > Also, don't forget explicit object function bodies and their type behave a
> > lot more like static functions than member functions.
>
> Yes, that is one of the next thing's on my list to implement. At the moment
> they are still member function pointer types.
> My current plan is;
> 1. Pass reference to object when calling explicit object member functions.
> 2. Convert the function type of explicit object member functions to regular
> function types.
> 3. Make sure calling explicit object member functions as member functions still
> works.
> 4. finally, implement calling explicit object member functions through a
> pointer to function. (Which should hopefully be free to implement.)

What about forbidding the use of `this` and no implicit lookup in
bodies? You basically have to implement body parsing like it's a
static. You've probably thought of this, just making sure you don't
throw away a bunch of effort on the odd chance you missed it.

> A little off topic, but my function pointer wrapper example above got me
> thinking about things and I don't have a better place to share them.

Like programmable surrogates? Perhaps https://wg21.link/p2826 might be
of interest.

> The example only really feels good because the implicit conversion is already
> fairly natural for the type. What about cases where an implicit conversion
> doesn't make sense, but still wants to benefit from such a pattern? I have to
> wonder if a solution would be allowing private conversion operators to be
> selected when calling an explicit object member function.

Intriguing thought.

> I guess that doesn't work properly when calling it through a pointer to the
> function though, so surely this would have more issues than it's worth.
> I have some other bad ideas on how to facilitate this, but they are far too
> cursed to share here, so I will stop stalling and get to work.

:magic wand emoji:

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (11 preceding siblings ...)
  2023-08-20 14:21 ` gasper.azman at gmail dot com
@ 2023-08-21  1:24 ` waffl3x at protonmail dot com
  2023-08-21 15:17 ` barry.revzin at gmail dot com
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-08-21  1:24 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #13 from waffl3x <waffl3x at protonmail dot com> ---
I am finding myself realizing that implementing this as a member function and
turning off member function bits seems to be more difficult than implementing
it as a static function and implementing member function bits will be.
However, I am uncertain on the differences in what is in scope in static member
functions and implicit object member functions are, and whether explicit object
member functions scope is equal to either of them. Are you required to access
member type aliases through the type of the explicit object parameter? Upon
typing this I'm realizing that cases that deduce the explicit object parameter
would need to access it through the template type, so I guess the answer is
yes?

struct S {
    using my_type = int;
    void f0(this S, my_type) {}
    void g0(this S) {
        my_type local;
    }
};

struct S {
    using my_type = int;
    void f1(this S, S::my_type) {}
    void g1(this S) {
        S::my_type local;
    }
};

Of these cases, is f0 or f1 and g0 or g1 correct? I assume the answer is f1 and
g1.
And does the answer change when the type is deduced instead?

struct S {
    using my_type = int;
    template<typename Self>
    void f0(this Self, my_type) {}
    template<typename Self>
    void g0(this Self) {
        my_type local;
    }
};

struct S {
    using my_type = int;
    template<typename Self>
    void f0(this Self, Self::my_type) {}
    template<typename Self>
    void g0(this Self) {
        Self::my_type local;
    }
};

When deduced, f0 or f1 and g0 or g1? I would definitely think f1 and g1 now.

Really, writing the question out I feel like I know the answer now, but since I
was uncertain in the first place I still better ask, just in case.

(In reply to Gašper Ažman from comment #12)

> Converting to a pointer-type is not weird; it's converting to pointer
> to your own type that is. Any proxy object with a conversion operator
> to its underlying will have that if the underlying happens to be a
> pointer type. Such a proxy object might well forward methods directly
> to the underlying object via a conversion instead of stamping out a
> body for each cv-ref qualifier.
> 
> > Granted, I think this type of use should also have some sort of warning
> > available as it is still weird.
> 
> I disagree; conversion to your own type I think is a reasonable
> warning (unless you have a conversion operator in the same class)
> because it can come with a fixit hint (replace with reference to S
> instead). All other types are legit.
To be clear, when I say a warning should be available, I don't mean to imply
the thing it warns for isn't potentially legitimate. There's quite a few
warnings for legitimate things that you don't want to accidentally do but are
legitimate, or even common. The best example I have is everything under
-Wconversion, I know some people find suppressing it with explicit casts
annoying, but the errors that can come about through accidental conversions are
severe enough to justify using it in my opinion.

I would extend that rationale to not suppressing warnings for S* when a
conversion operator is present. Just because the conversion operator exists
that makes a call to that function (in the absence of any other overloads) well
formed does not mean that one meant to declare the xobj as S*.

> > I think a warning for declaring an explicit object parameter as a pointer to
> > base, derived, or deduced type should be in, since a reference is probably the
> > best choice in that case.
> 
> I definitely agree that this warning is reasonable.
> 
> > Perhaps deduced type shouldn't be included in that
> > warning, as there are cases that are kind of compelling for having that, one
> > could trap implicit conversions to any pointer type that way on derived
> > classes.
> 
> Yeah, deduced is legit, no warning for that one unless we discover
> active pathologies.
Noted, warn for pointer to base or derived, but not to pointer to deduced. Or
at least not behind the same warning flag.

> > To elaborate on what I said above, I still think a warning when using a type
> > that is not related to the class should be provided.
> 
> Strong disagree, that'll break a lot of code I actually intend to
> write. Not stamping out additional template instantiations /  better
> ABI by having implicit conversions will, I expect, be quite the common
> implementation trick (for instance, any member algorithm on a vector
> that doesn't change size can be called on an equivalent span instead
> and therefore be passed in registers). This can be an implementation
> detail of vector, so that vector and array can share template
> instantiations, for instance.
I think you should recognize that these exotic use cases are just that, exotic.
I don't think I should leave warnings that might be useful for the average user
off the table just because you or I would never enable that warning. Writing
this I'm now realizing the case I mentioned earlier that you said is not weird
would be better referred to as "exotic", I don't want to imply any negative
connotations.

I REALLY like the new exotic things we can do with this feature.

In short, I agree that this warning would be detrimental for implementers and
advanced users, but I don't think that's a reason to not have it optionally
available. (Granted, I have changed my mind a bit as I note below.)

> > Even given that my example
> > above presents a legitimate pattern, I think it's use is infrequent enough to
> > provide an optional warning for this. I question if there's any value in
> > suppressing the warning when there are legitimate conversions present, as it
> > would no longer inform the user that they might have done something by mistake.
> 
> I think my ruminations above give a good example of why such false
> positives should definitely be expected in well-behaved code.
Yeah, false positives would be impossible to avoid, any warning that tries to
take into account available conversions would need to document that false
positives are known to occur, and it won't be fixed. If one doesn't like that,
they shouldn't use the warning.

> > Essentially, since it's not possible to warn that there are no viable
> > conversions without false positives occurring, I think the warning should be
> > present simply because you are doing something weird, not because you are
> > declaring a function that won't be selected by overload resolution.
> 
> Yes, but you can get a pointer to it and call it directly. Might be a
> useful way to pass overload sets.
Could you elaborate on this, it sounds interesting but I think I'm not
understanding fully.

> > Just to reiterate, I fully agree that both warnings should be behind a flag. I
> > think I would propose that the first (warning for pointer to base, derived, or
> > deduced type in an explicit object parameter) should be turned on by default,
> > while the second should be turned off by default.
> 
> I'm not sure the second one should even exist, as it's bound to be
> even more annoying than -Wshadow.
Yeah, I run a LOT of warnings and I had to turn off -Wshadow. Too many false
positives, negligible benefit, and it can even make your code worse at times if
you try to follow it. I certainly wouldn't enable the second warning I referred
to here, I just don't think whether I would use a warning or not is a measure
on it's value.

Or maybe my philosophy on warnings is just flawed out of the gate? Perhaps I
should just forget about warning against any exotic use cases until there's
precedent that users want it.
I can imagine someone might accidentally put an unrelated type as an explicit
object parameter when they meant to put the type, but thats just it, I'm
imagining it. So I guess I'll wait for more precedent to emerge before I think
about it more.
I guess that's pretty much what you meant when you said this above.
> Yeah, deduced is legit, no warning for that one unless we discover
> active pathologies.

As a side note, through writing this I realized that I'm not actually sure if
there's a legitimate reason to take a reference to a base type as an explicit
object parameter, maybe just as a shortcut I guess instead of having to upcast
on each use. (With that said, taking a base by value to intentionally slice the
object would be legit)

> >
> > struct S : B {
> >     int f0(this B*) {} // warning 1, on by default
> >     int f1(this S*) {} // warning 1, on by default
> >     int f2(this auto*) {} // warning 1, on by default?, separate warning?
> >
> >     int f3(this int) {} // warning 2, off by default(?)
> > };
> 
> I say no warning on f2. S could be a CRTP-sans-CRTP mixin that expect
> that conversion to exist.
> 
> >
> > On the other hand, warning 2 could be split into 2 warnings, where one would
> > warn for a "weird" explicit object parameter, while the other would warn for
> > uncallable functions due to a lack of implicit conversions.
> > warning 2: weird explicit object parameter
> > warning 3: uncallable function (possibly has false positives)
> 
> I expect f3 to be a very common thing.

Given my thoughts above, I now agree that only f0 and f1 in the example should
be have a warning emitted. If precedent emerges to add more warnings it can be
done later, I was definitely getting ahead of myself.

> >
> > > Also, don't forget explicit object function bodies and their type behave a
> > > lot more like static functions than member functions.
> >
> > Yes, that is one of the next thing's on my list to implement. At the moment
> > they are still member function pointer types.
> > My current plan is;
> > 1. Pass reference to object when calling explicit object member functions.
> > 2. Convert the function type of explicit object member functions to regular
> > function types.
> > 3. Make sure calling explicit object member functions as member functions still
> > works.
> > 4. finally, implement calling explicit object member functions through a
> > pointer to function. (Which should hopefully be free to implement.)
> 
> What about forbidding the use of `this` and no implicit lookup in
> bodies? You basically have to implement body parsing like it's a
> static. You've probably thought of this, just making sure you don't
> throw away a bunch of effort on the odd chance you missed it.

Yeah, but previously I thought it would be easier to continue treating it as a
member function. At this point I don't think that is actually the case (hence
my question at the top.)

> > A little off topic, but my function pointer wrapper example above got me
> > thinking about things and I don't have a better place to share them.
> 
> Like programmable surrogates? Perhaps https://wg21.link/p2826 might be
> of interest.
> 
I'll be sure to check it out when I have a chance, I'm going to take a break
now though, I need a reset since I was probably attacking this wrong from the
start. I'm pretty sure my current problem (rvalue and lvalue overloads are
considered equivalent) will be fixed by switching to treating the explicit
object member functions as if they are static functions.

Originally I had thought that it would be harder to modify the code that forms
calls to member functions, but it completely slipped my mind that you can also
call static member functions the same way as member functions, so that isn't as
big an issue as I thought. Ah well, I got to have fun reading overload
resolution code, that will probably be helpful when implementing other things
(I hope).

It was definitely a mistake the start at member functions and disable
irrelevant/incorrect member function functionality though. Despite this sharing
more with implicit object member functions in terms of the standard, on the
implementation side xobj functions definitely shares more with static member
functions. Hindsight is 20/20 as they say.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (12 preceding siblings ...)
  2023-08-21  1:24 ` waffl3x at protonmail dot com
@ 2023-08-21 15:17 ` barry.revzin at gmail dot com
  2023-08-25 11:28 ` waffl3x at protonmail dot com
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: barry.revzin at gmail dot com @ 2023-08-21 15:17 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #14 from Barry Revzin <barry.revzin at gmail dot com> ---
> I am finding myself realizing that implementing this as a member function and turning off member function bits seems to be more difficult than implementing it as a static function and implementing member function bits will be.

That's how I implemented this in EDG - static member functions that just have
some extra powers. 

> Of these cases, is f0 or f1 and g0 or g1 correct? I assume the answer is f1 and g1.

Both are correct - you're still a member of S, so you don't have to qualify
S::my_type (I mean, you can, it's not incorrect, but it's just not necessary -
means the same thing either way).

> When deduced, f0 or f1 and g0 or g1? I would definitely think f1 and g1 now.

These now might actually mean different things. Unqualified my_type is still
valid and means S::my_type (i.e. int). But Self::my_type could now mean a
different type. Merging the two examples:

struct S {
    using my_type = int;

    template<typename Self>
    void f0(this Self, my_type);

    template<typename Self>
    void f1(this Self, Self::my_type);
};

struct D : S {
    using my_type = double;
};

D().f0(2.0); // calls S::f0<D>, which takes an int
D().f1(2.0); // calls S::f1<D>, which takes a double

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (13 preceding siblings ...)
  2023-08-21 15:17 ` barry.revzin at gmail dot com
@ 2023-08-25 11:28 ` waffl3x at protonmail dot com
  2023-08-31  6:50 ` waffl3x at protonmail dot com
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-08-25 11:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #15 from waffl3x <waffl3x at protonmail dot com> ---
Created attachment 55793
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=55793&action=edit
inital support for P0847 explicit-object-parameter

Alright, I finalized something that I hope is worthy of criticism. I haven't
ran tests on it yet but I think it should be relatively stable. My first time
around I made the mistake of having hard failing TREE_CHECKs in if conditions,
and I'm pretty sure that was causing problems with the tests (I saw a lot of
segfaults), but I'm fairly sure it should be good this time (not that I shared
the first one).

I will probably start tests first thing tomorrow, hopefully I can figure out
how to make it take less than 4-8 hours.

I'm pretty happy with where I put most things, I didn't add anything to the
core tree nodes, I instead used tree_decl_common::decl_flag_3 for PARM_DECL,
but I added a member to lang_decl_base, hopefully this is satisfactory.

As for what I know works right now, the below program outputs 15, 25, 35, 45 as
you would expect. I haven't tried lambda's but I am sure they don't work. I
have not tried anything with inheritance, I wouldn't bet on it working but I
wouldn't bet against it. I have not tried implicit conversions, but I have a
feeling they probably work. I was planning on implementing rejection of
qualifiers on xobj member functions but I forgot, so that will come tomorrow. I
also have to implement errors when trying to declare a xobj parameter in a
function type. I haven't tried taking the address of an xobj member function,
but I have a hunch it will work, they are almost entirely treated as static
member functions at the moment. Speaking of that, the function declaration gets
pretty printed as a static function at the moment too.

So as you can see, there's still lots to do, but it shouldn't be as hard now
that I am more familiar with the code base.

Something I'm not especially happy with is how the error checking is strewn
around. I tried to put it where it is most relevant, but prioritized putting it
where I could get the best diagnostics, but I'm probably missing some things I
could be doing to better group it together. I am also not happy with the
quality of all of the diagnostics, I want to improve on that as I learn the
quirks of the utilities.

Please criticize, I am certain I am still doing some stuff wrong, so I would
appreciate any input so I can correct those mistakes.

Here is the aforementioned program that I know to work on my system. Surely
nothing can go wrong, but who knows.

#include <cstdio>
struct S {
    int _a;
    int my_func(this S& s) {
        return s._a + 5;
    }
    int my_func(this S const& s) {
        return s._a + 15;
    }
    int my_func(this S&& s) {
        return s._a + 25;
    }
    int my_func(this S const&& s) {
        return s._a + 35;
    }
    template<typename Self>
    int my_func_dispatch(this Self&& self) {
        return static_cast<Self&&>(self).my_func();
    }
};

int main()
{
    S s{10};

    printf("%d\n", s.my_func_dispatch());
    printf("%d\n", static_cast<S const&>(s).my_func_dispatch());
    printf("%d\n", static_cast<S&&>(s).my_func_dispatch());
    printf("%d\n", static_cast<S const&&>(s).my_func_dispatch());
}

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (14 preceding siblings ...)
  2023-08-25 11:28 ` waffl3x at protonmail dot com
@ 2023-08-31  6:50 ` waffl3x at protonmail dot com
  2023-08-31  9:28 ` gasper.azman at gmail dot com
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-08-31  6:50 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #16 from waffl3x <waffl3x at protonmail dot com> ---
Just gotta note that the patch posted here had an oversight, it never worked as
I hoped. The good news is, I submitted a finalized patch to the patch maillist,
just before I have to leave. Thanks for the help everyone, I will check in but
it will probably be a while before I can work on anything in a dedicated
fashion for a while. I will certainly respond to any chatter on the thread of
my patch if anything comes into question though. I have to go catch a plane
now, thanks again.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (15 preceding siblings ...)
  2023-08-31  6:50 ` waffl3x at protonmail dot com
@ 2023-08-31  9:28 ` gasper.azman at gmail dot com
  2023-09-02  8:54 ` waffl3x at protonmail dot com
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: gasper.azman at gmail dot com @ 2023-08-31  9:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #17 from Gašper Ažman <gasper.azman at gmail dot com> ---
Read through the patch quickly, want to suggest a few tests.

When a lambda has captures, the explicit object parameter is used to get at
them *silently*, if they are related, otherwise the program is ill-formed:

int x = 42;
auto f1 = [x](this auto&&) {
   return x;
};
auto f2 = [](this auto&&) { return 42; }

static_cast<int(*)(decltype(f1)&)>(decltype(f1)::operator()); // OK
static_cast<int(*)(int&)>(decltype(f1)::operator()); // ERROR
static_cast<int(*)(int&)>(decltype(f2)::operator()); // OK

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (16 preceding siblings ...)
  2023-08-31  9:28 ` gasper.azman at gmail dot com
@ 2023-09-02  8:54 ` waffl3x at protonmail dot com
  2023-09-02 22:30 ` gasper.azman at gmail dot com
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2023-09-02  8:54 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #18 from waffl3x <waffl3x at protonmail dot com> ---
(In reply to Gašper Ažman from comment #17)
> Read through the patch quickly, want to suggest a few tests.
> 
> When a lambda has captures, the explicit object parameter is used to get at
> them *silently*, if they are related, otherwise the program is ill-formed:
> 
> int x = 42;
> auto f1 = [x](this auto&&) {
>    return x;
> };
> auto f2 = [](this auto&&) { return 42; }
> 
> static_cast<int(*)(decltype(f1)&)>(decltype(f1)::operator()); // OK
> static_cast<int(*)(int&)>(decltype(f1)::operator()); // ERROR
> static_cast<int(*)(int&)>(decltype(f2)::operator()); // OK

Ah I see, thanks for the input. I was actually wondering about that, especially
if you were expected to use the explicit object parameter to access captures.
Is my understanding correct that the second case would not be an error if
captures were not used in the body of the lambda? Based on your wording I would
believe that is the case, so implementing this behavior would not be as simple
as just disallowing unrelated deduced types when there are captures.

Unfortunately, I will not have access to my computer for a while more, I plan
on setting up an environment at another computer and fixing the formatting
errors that were noted, but I will wait until I have access to my computer
before I work on it more seriously I think.

Thanks a lot for looking at the patch though, I really appreciate the time
you've taken.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (17 preceding siblings ...)
  2023-09-02  8:54 ` waffl3x at protonmail dot com
@ 2023-09-02 22:30 ` gasper.azman at gmail dot com
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: gasper.azman at gmail dot com @ 2023-09-02 22:30 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #19 from Gašper Ažman <gasper.azman at gmail dot com> ---
Correct, the use of the capture is the source of the error, not the
instantiation with an unrelated type.

On Sat, Sep 2, 2023, 09:54 waffl3x at protonmail dot com <
gcc-bugzilla@gcc.gnu.org> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609
>
> --- Comment #18 from waffl3x <waffl3x at protonmail dot com> ---
> (In reply to Gašper Ažman from comment #17)
> > Read through the patch quickly, want to suggest a few tests.
> >
> > When a lambda has captures, the explicit object parameter is used to get
> at
> > them *silently*, if they are related, otherwise the program is
> ill-formed:
> >
> > int x = 42;
> > auto f1 = [x](this auto&&) {
> >    return x;
> > };
> > auto f2 = [](this auto&&) { return 42; }
> >
> > static_cast<int(*)(decltype(f1)&)>(decltype(f1)::operator()); // OK
> > static_cast<int(*)(int&)>(decltype(f1)::operator()); // ERROR
> > static_cast<int(*)(int&)>(decltype(f2)::operator()); // OK
>
> Ah I see, thanks for the input. I was actually wondering about that,
> especially
> if you were expected to use the explicit object parameter to access
> captures.
> Is my understanding correct that the second case would not be an error if
> captures were not used in the body of the lambda? Based on your wording I
> would
> believe that is the case, so implementing this behavior would not be as
> simple
> as just disallowing unrelated deduced types when there are captures.
>
> Unfortunately, I will not have access to my computer for a while more, I
> plan
> on setting up an environment at another computer and fixing the formatting
> errors that were noted, but I will wait until I have access to my computer
> before I work on it more seriously I think.
>
> Thanks a lot for looking at the patch though, I really appreciate the time
> you've taken.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (18 preceding siblings ...)
  2023-09-02 22:30 ` gasper.azman at gmail dot com
@ 2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-01-09 21:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #20 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:f9fbf93dc82525a0f54a2293b7ec92d65776bf19

commit r14-7074-gf9fbf93dc82525a0f54a2293b7ec92d65776bf19
Author: waffl3x <waffl3x@protonmail.com>
Date:   Sun Jan 7 00:00:10 2024 +0000

    c++: P0847R7 (deducing this) - prerequisite changes. [PR102609]

    Adds the xobj_flag member to lang_decl_fn and a corresponding member access
    macro and predicate to support the addition of explicit object member
    functions. Additionally, since explicit object member functions are also
    non-static member functions, we need to change uses of
    DECL_NONSTATIC_MEMBER_FUNCTION_P to clarify whether they intend to include
    or exclude them.

            PR c++/102609

    gcc/cp/ChangeLog:

            * cp-tree.h (struct lang_decl_fn): New data member.
            (DECL_NONSTATIC_MEMBER_FUNCTION_P): Poison.
            (DECL_IOBJ_MEMBER_FUNCTION_P): Define.
            (DECL_FUNCTION_XOBJ_FLAG): Define.
            (DECL_XOBJ_MEMBER_FUNCTION_P): Define.
            (DECL_OBJECT_MEMBER_FUNCTION_P): Define.
            (DECL_FUNCTION_MEMBER_P): Don't use
            DECL_NONSTATIC_MEMBER_FUNCTION_P.
            (DECL_CONST_MEMFUNC_P): Likewise.
            (DECL_VOLATILE_MEMFUNC_P): Likewise.
            (DECL_NONSTATIC_MEMBER_P): Likewise.
            * module.cc (trees_out::lang_decl_bools): Handle xobj_flag.
            (trees_in::lang_decl_bools): Handle xobj_flag.
            * call.cc (build_this_conversion)
            (add_function_candidate)
            (add_template_candidate_real)
            (add_candidates)
            (maybe_warn_class_memaccess)
            (cand_parms_match)
            (joust)
            (do_warn_dangling_reference)
            * class.cc (finalize_literal_type_property)
            (finish_struct)
            (resolve_address_of_overloaded_function)
            * constexpr.cc (is_valid_constexpr_fn)
            (cxx_bind_parameters_in_call)
            * contracts.cc (build_contract_condition_function)
            * cp-objcp-common.cc (cp_decl_dwarf_attribute)
            * cxx-pretty-print.cc (cxx_pretty_printer::postfix_expression)
            (cxx_pretty_printer::declaration_specifiers)
            (cxx_pretty_printer::direct_declarator)
            * decl.cc (cp_finish_decl)
            (grok_special_member_properties)
            (start_preparsed_function)
            (record_key_method_defined)
            * decl2.cc (cp_handle_deprecated_or_unavailable)
            * init.cc (find_uninit_fields_r)
            (build_offset_ref)
            * lambda.cc (lambda_expr_this_capture)
            (maybe_generic_this_capture)
            (nonlambda_method_basetype)
            * mangle.cc (write_nested_name)
            * method.cc (early_check_defaulted_comparison)
            (skip_artificial_parms_for)
            (num_artificial_parms_for)
            * pt.cc (is_specialization_of_friend)
            (determine_specialization)
            (copy_default_args_to_explicit_spec)
            (check_explicit_specialization)
            (tsubst_contract_attribute)
            (check_non_deducible_conversions)
            (more_specialized_fn)
            (maybe_instantiate_noexcept)
            (register_parameter_specializations)
            (value_dependent_expression_p)
            * search.cc (shared_member_p)
            (lookup_member)
            (field_access_p)
            * semantics.cc (finish_omp_declare_simd_methods)
            * tree.cc (lvalue_kind)
            * typeck.cc (invalid_nonstatic_memfn_p): Don't use
            DECL_NONSTATIC_MEMBER_FUNCTION_P.

    libcc1/ChangeLog:

            * libcp1plugin.cc (plugin_pragma_push_user_expression): Don't use
            DECL_NONSTATIC_MEMBER_FUNCTION_P.

    Signed-off-by: Waffl3x <waffl3x@protonmail.com>
    Co-authored-by: Jason Merrill <jason@redhat.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (19 preceding siblings ...)
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
@ 2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
                   ` (7 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-01-09 21:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #21 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:fbc980d85149409ce62c22f48d3693113803929e

commit r14-7075-gfbc980d85149409ce62c22f48d3693113803929e
Author: waffl3x <waffl3x@protonmail.com>
Date:   Sun Jan 7 00:01:48 2024 +0000

    c++: P0847R7 (deducing this) - initial functionality. [PR102609]

    This implements the initial functionality for P0847R7.  CWG2789 is
    implemented, but instead of "same type" for the object parameters we take
    correspondence into account instead.  Without this alteration, the behavior
    here would be slightly different than the behavior with constrained member
    function templates, which I believe would be undesirable.

    There are a few outstanding issues related to xobj member functions
    overloading iobj member functions that are introduced by using
declarations.
    Unfortunately, fixing this will be a little more involved and will have to
    be pushed back until later.

    Most diagnostics have been split out into another patch to improve its
    clarity and allow all the strictly functional changes to be more
    distinct. Explicit object lambdas and CWG2586 are addressed in a follow up
    patch.

            PR c++/102609

    gcc/cp/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - initial functionality.
            * class.cc (xobj_iobj_parameters_correspond): New function, checks
            for corresponding object parameters between xobj and iobj member
            functions.
            (add_method): Handle object parameters of xobj member functions,
use
            xobj_iobj_parameters_correspond.
            * call.cc (build_over_call): Refactor, handle xobj member
functions.
            (cand_parms_match): Handle object parameters of xobj and iobj
member
            functions, use xobj_iobj_parameters_correspond.
            * cp-tree.h (enum cp_decl_spec): Add ds_this, add comments.
            * decl.cc (grokfndecl): Add xobj_func_p parameter.  For xobj member
            functions, Set xobj_flag, don't set static_function flag.
            (grokdeclarator): Handle xobj member functions, tell grokfndecl.
            (grok_op_properties): Don't error for xobj operators.
            * parser.cc (cp_parser_decl_specifier_seq): Handle this specifier.
            (cp_parser_parameter_declaration): Set default argument to
            "this_identifier" for xobj parameters.
            (set_and_check_decl_spec_loc): Add "this", add comments.
            * tree.cc (build_min_non_dep_op_overload): Handle xobj operators.
            * typeck.cc (cp_build_addr_expr_1): Handle address-of xobj member
            functions.

    gcc/testsuite/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - initial functionality.
            * g++.dg/cpp23/explicit-obj-basic1.C: New test.
            * g++.dg/cpp23/explicit-obj-basic2.C: New test.
            * g++.dg/cpp23/explicit-obj-basic3.C: New test.
            * g++.dg/cpp23/explicit-obj-basic4.C: New test.
            * g++.dg/cpp23/explicit-obj-basic5.C: New test.
            * g++.dg/cpp23/explicit-obj-by-value1.C: New test.
            * g++.dg/cpp23/explicit-obj-by-value2.C: New test.
            * g++.dg/cpp23/explicit-obj-by-value3.C: New test.
            * g++.dg/cpp23/explicit-obj-by-value4.C: New test.
            * g++.dg/cpp23/explicit-obj-constraints.C: New test.
            * g++.dg/cpp23/explicit-obj-constraints2.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-mem-arrow.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-mem-assignment.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-mem-call.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-mem-subscript.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-non-mem-dep.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-non-mem-non-dep.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-non-mem.h: New test.
            * g++.dg/cpp23/explicit-obj-ops-requires-mem.C: New test.
            * g++.dg/cpp23/explicit-obj-ops-requires-non-mem.C: New test.
            * g++.dg/cpp23/explicit-obj-redecl.C: New test.
            * g++.dg/cpp23/explicit-obj-redecl2.C: New test.
            * g++.dg/cpp23/explicit-obj-redecl3.C: New test.
            * g++.dg/cpp23/explicit-obj-redecl4.C: New test.

    Signed-off-by: Waffl3x <waffl3x@protonmail.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (20 preceding siblings ...)
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
@ 2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
                   ` (6 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-01-09 21:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #22 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:f8bf6a69e260a5f1aa0dbf89a6e4bcdf1a24af5d

commit r14-7076-gf8bf6a69e260a5f1aa0dbf89a6e4bcdf1a24af5d
Author: waffl3x <waffl3x@protonmail.com>
Date:   Sun Jan 7 00:03:19 2024 +0000

    c++: P0847R7 (deducing this) - diagnostics. [PR102609]

    Diagnostics for xobj member functions. Also includes some diagnostics for
    xobj lambdas which are not implemented here. CWG2554 is also implemented
    here, we explicitly error when an xobj member function overrides a virtual
    function.

            PR c++/102609

    gcc/c-family/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - diagnostics.
            * c-cppbuiltin.cc (c_cpp_builtins): Define
            __cpp_explicit_this_parameter=202110L feature test macro.

    gcc/cp/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - diagnostics.
            * class.cc (resolve_address_of_overloaded_function): Diagnostics.
            * cp-tree.h (TFF_XOBJ_FUNC): Define.
            * decl.cc (grokfndecl): Diagnostics.
            (grokdeclarator): Diagnostics.
            * error.cc (dump_aggr_type): Pass TFF_XOBJ_FUNC.
            (dump_lambda_function): Formatting for xobj lambda.
            (dump_function_decl): Pass TFF_XOBJ_FUNC.
            (dump_parameters): Formatting for xobj member functions.
            (function_category): Formatting for xobj member functions.
            * parser.cc (cp_parser_decl_specifier_seq): Diagnostics.
            (cp_parser_parameter_declaration): Diagnostics.
            * search.cc (look_for_overrides_here): Make xobj member functions
            override.
            (look_for_overrides_r): Reject an overriding xobj member function
            and diagnose it.
            * semantics.cc (finish_this_expr): Diagnostics.
            * typeck.cc (cp_build_addr_expr_1): Diagnostics.

    gcc/testsuite/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - diagnostics.
            * g++.dg/cpp23/feat-cxx2b.C: Test existance and value of
            __cpp_explicit_this_parameter feature test macro.
            * g++.dg/cpp26/feat-cxx26.C: Likewise.
            * g++.dg/cpp23/explicit-obj-cxx-dialect-A.C: New test.
            * g++.dg/cpp23/explicit-obj-cxx-dialect-B.C: New test.
            * g++.dg/cpp23/explicit-obj-cxx-dialect-C.C: New test.
            * g++.dg/cpp23/explicit-obj-cxx-dialect-D.C: New test.
            * g++.dg/cpp23/explicit-obj-cxx-dialect-E.C: New test.
            * g++.dg/cpp23/explicit-obj-diagnostics1.C: New test.
            * g++.dg/cpp23/explicit-obj-diagnostics2.C: New test.
            * g++.dg/cpp23/explicit-obj-diagnostics3.C: New test.
            * g++.dg/cpp23/explicit-obj-diagnostics4.C: New test.
            * g++.dg/cpp23/explicit-obj-diagnostics5.C: New test.
            * g++.dg/cpp23/explicit-obj-diagnostics6.C: New test.
            * g++.dg/cpp23/explicit-obj-diagnostics7.C: New test.

    Signed-off-by: Waffl3x <waffl3x@protonmail.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (21 preceding siblings ...)
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
@ 2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
  2024-01-09 21:57 ` cvs-commit at gcc dot gnu.org
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-01-09 21:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #23 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:07d09f0af100a9873982fba663800d87bfd73585

commit r14-7077-g07d09f0af100a9873982fba663800d87bfd73585
Author: waffl3x <waffl3x@protonmail.com>
Date:   Sun Jan 7 00:53:32 2024 +0000

    c++: P0847R7 (deducing this) - xobj lambdas. [PR102609]

    This implements support for xobj lambdas.  There are extensive tests
    included, but not exhaustive.  Dependent lambdas should work and have been
    tested lightly, but we need more exhaustive tests for them.

            PR c++/102609

    gcc/cp/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - xobj lambdas.
            * lambda.cc (build_capture_proxy): Don't fold direct object types.
            * parser.cc (cp_parser_lambda_declarator_opt): Handle xobj lambdas,
            diagnostics.  Comments also updated.
            * pt.cc (tsubst_function_decl): Handle xobj lambdas.  Check object
            type of xobj lambda call operator, diagnose incorrect types.
            (tsubst_lambda_expr): Update comment.
            * semantics.cc (finish_decltype_type): Also consider by-value
object
            parameter qualifications.

    gcc/testsuite/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - xobj lambdas.
            * g++.dg/cpp23/explicit-obj-diagnostics8.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda1.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda10.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda11.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda12.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda13.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda2.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda3.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda4.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda5.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda6.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda7.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda8.C: New test.
            * g++.dg/cpp23/explicit-obj-lambda9.C: New test.

    Signed-off-by: Waffl3x <waffl3x@protonmail.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (22 preceding siblings ...)
  2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
@ 2024-01-09 21:57 ` cvs-commit at gcc dot gnu.org
  2024-01-11 20:47 ` corentinjabot at gmail dot com
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2024-01-09 21:57 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #24 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:bfad006b88ec26e91b7edf9cf9ad4aaf9b8a9727

commit r14-7078-gbfad006b88ec26e91b7edf9cf9ad4aaf9b8a9727
Author: waffl3x <waffl3x@protonmail.com>
Date:   Sun Jan 7 23:10:00 2024 +0000

    c++: P0847R7 (deducing this) - CWG2586 [PR102609]

    This adds support for defaulted comparison operators and copy/move
    assignment operators, as well as allowing user defined xobj copy/move
    assignment operators. It turns out defaulted comparison operators already
    worked though, so this just adds a test for them. Defaulted comparison
    operators were not so nice and required a bit of a hack. Should work fine
    though!

    The diagnostics leave something to be desired, and there are some things
    that could be improved with more extensive design changes. There are a few
    notes left indicating where I think we could make improvements.

    Aside from some small bugs, with this commit xobj member functions should
be
    feature complete.

            PR c++/102609

    gcc/cp/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - CWG2586.
            * decl.cc (copy_fn_p): Accept xobj copy assignment functions.
            (move_signature_fn_p): Accept xobj move assignment functions.
            * method.cc (do_build_copy_assign): Handle defaulted xobj member
            functions.
            (defaulted_late_check): Comment.
            (defaultable_fn_check): Comment.

    gcc/testsuite/ChangeLog:

            PR c++/102609
            C++23 P0847R7 (deducing this) - CWG2586.
            * g++.dg/cpp23/explicit-obj-basic6.C: New test.
            * g++.dg/cpp23/explicit-obj-default1.C: New test.
            * g++.dg/cpp23/explicit-obj-default2.C: New test.

    Signed-off-by: Waffl3x <waffl3x@protonmail.com>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (23 preceding siblings ...)
  2024-01-09 21:57 ` cvs-commit at gcc dot gnu.org
@ 2024-01-11 20:47 ` corentinjabot at gmail dot com
  2024-01-11 21:08 ` waffl3x at protonmail dot com
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: corentinjabot at gmail dot com @ 2024-01-11 20:47 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

corentinjabot at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |corentinjabot at gmail dot com

--- Comment #25 from corentinjabot at gmail dot com ---
Hey folks.
Congrats on landing support for deducing this in GCC.

While there is no spec for it, after discussion here,
https://github.com/itanium-cxx-abi/cxx-abi/issues/148 explicit objects
parameters are mangled with `H`
This is the form that has been adopted for Clang.

The reason we need mangling is because WG21 made the following well-formed (and
that was reaffirmed. In fact, some complexity was added by P2797)


   struct S {
     static void f(S);
     void f(this S);
   };

And we need a way to distinguish both functions
I wasn't sure you were aware of this; I hope that form of mangling will work
for you.


Thanks

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (24 preceding siblings ...)
  2024-01-11 20:47 ` corentinjabot at gmail dot com
@ 2024-01-11 21:08 ` waffl3x at protonmail dot com
  2024-01-11 22:00 ` gasper.azman at gmail dot com
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2024-01-11 21:08 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #26 from waffl3x <waffl3x at protonmail dot com> ---
(In reply to corentinjabot from comment #25)
> Hey folks.
> Congrats on landing support for deducing this in GCC.

Thanks!

> While there is no spec for it, after discussion here,
> https://github.com/itanium-cxx-abi/cxx-abi/issues/148 explicit objects
> parameters are mangled with `H`
> This is the form that has been adopted for Clang.
> 
> The reason we need mangling is because WG21 made the following well-formed
> (and that was reaffirmed. In fact, some complexity was added by P2797)
> 
> 
>    struct S {
>      static void f(S);
>      void f(this S);
>    };
> 
> And we need a way to distinguish both functions
> I wasn't sure you were aware of this; I hope that form of mangling will work
> for you.
> 
> 
> Thanks

I don't have the experience to comment but my gut says this is a weird
outcome. Oh well! I think I know how to implement this so I'll give it
a go at some point today. If I have any trouble I'll leave it for
someone else.

Thanks for informing us.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (25 preceding siblings ...)
  2024-01-11 21:08 ` waffl3x at protonmail dot com
@ 2024-01-11 22:00 ` gasper.azman at gmail dot com
  2024-01-11 22:01 ` jakub at gcc dot gnu.org
  2024-01-12  0:26 ` waffl3x at protonmail dot com
  28 siblings, 0 replies; 30+ messages in thread
From: gasper.azman at gmail dot com @ 2024-01-11 22:00 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #27 from Gašper Ažman <gasper.azman at gmail dot com> ---
I think there is an example in the standard that distinguishes those two as
far as overload resolution is concerned.

On Thu, Jan 11, 2024, 21:08 waffl3x at protonmail dot com <
gcc-bugzilla@gcc.gnu.org> wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609
>
> --- Comment #26 from waffl3x <waffl3x at protonmail dot com> ---
> (In reply to corentinjabot from comment #25)
> > Hey folks.
> > Congrats on landing support for deducing this in GCC.
>
> Thanks!
>
> > While there is no spec for it, after discussion here,
> > https://github.com/itanium-cxx-abi/cxx-abi/issues/148 explicit objects
> > parameters are mangled with `H`
> > This is the form that has been adopted for Clang.
> >
> > The reason we need mangling is because WG21 made the following
> well-formed
> > (and that was reaffirmed. In fact, some complexity was added by P2797)
> >
> >
> >    struct S {
> >      static void f(S);
> >      void f(this S);
> >    };
> >
> > And we need a way to distinguish both functions
> > I wasn't sure you were aware of this; I hope that form of mangling will
> work
> > for you.
> >
> >
> > Thanks
>
> I don't have the experience to comment but my gut says this is a weird
> outcome. Oh well! I think I know how to implement this so I'll give it
> a go at some point today. If I have any trouble I'll leave it for
> someone else.
>
> Thanks for informing us.
>
> --
> You are receiving this mail because:
> You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (26 preceding siblings ...)
  2024-01-11 22:00 ` gasper.azman at gmail dot com
@ 2024-01-11 22:01 ` jakub at gcc dot gnu.org
  2024-01-12  0:26 ` waffl3x at protonmail dot com
  28 siblings, 0 replies; 30+ messages in thread
From: jakub at gcc dot gnu.org @ 2024-01-11 22:01 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #28 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
It doesn't help that the mangling issue doesn't have implementation in form of
a mangling ABI patch, that would help to figure out e.g. whether it either H or
CV-qualifiers ref-qualifiers.

Anyway, I think for the mangler the likely change on the GCC side is
--- gcc/cp/mangle.cc.jj 2024-01-10 12:19:08.068675921 +0100
+++ gcc/cp/mangle.cc    2024-01-11 22:55:14.112489966 +0100
@@ -1247,6 +1247,8 @@ write_nested_name (const tree decl)
            write_char ('R');
        }
     }
+  else if (DECL_XOBJ_MEMBER_FUNCTION_P (decl))
+    write_char ('H');

   /* Is this a template instance?  */
   if (tree info = maybe_template_info (decl))
but one would need to add support for the libiberty demangler as well.

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Bug c++/102609] [C++23] P0847R7 - Deducing this
  2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
                   ` (27 preceding siblings ...)
  2024-01-11 22:01 ` jakub at gcc dot gnu.org
@ 2024-01-12  0:26 ` waffl3x at protonmail dot com
  28 siblings, 0 replies; 30+ messages in thread
From: waffl3x at protonmail dot com @ 2024-01-12  0:26 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609

--- Comment #29 from waffl3x <waffl3x at protonmail dot com> ---
https://cplusplus.github.io/CWG/issues/2789.html
My alteration to CWG2789 came up on reddit and I realized I should
probably post about it here.

Instead of:
"if both are non-static member functions, they have the same types for
their object parameters, and"
We assumed it would be more correct for it to consider corresponding
object parameters:
"if both are non-static member functions, they have corresponding
object parameters, and"

Without this change in wording, the behavior of overload resolution is
different for member function templates with constraints and member
functions that are not templates with constraints. I felt that would be
undesirable so I assumed that the second wording was closer to the
intentions behind CWG2789.

This is the behavior that's currently been implemented, are there any
objections?

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2024-01-12  0:26 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-05 15:56 [Bug c++/102609] New: [C++23] P0847R7 - Deducing this mpolacek at gcc dot gnu.org
2021-11-28 11:33 ` [Bug c++/102609] " pinskia at gcc dot gnu.org
2023-06-12 23:37 ` mpolacek at gcc dot gnu.org
2023-08-16 18:29 ` waffl3x at protonmail dot com
2023-08-16 18:48 ` gasper.azman at gmail dot com
2023-08-16 18:50 ` gasper.azman at gmail dot com
2023-08-16 21:58 ` waffl3x at protonmail dot com
2023-08-19  8:44 ` waffl3x at protonmail dot com
2023-08-19  9:38 ` redi at gcc dot gnu.org
2023-08-19  9:43 ` redi at gcc dot gnu.org
2023-08-19 16:10 ` gasper.azman at gmail dot com
2023-08-19 21:24 ` waffl3x at protonmail dot com
2023-08-20 14:21 ` gasper.azman at gmail dot com
2023-08-21  1:24 ` waffl3x at protonmail dot com
2023-08-21 15:17 ` barry.revzin at gmail dot com
2023-08-25 11:28 ` waffl3x at protonmail dot com
2023-08-31  6:50 ` waffl3x at protonmail dot com
2023-08-31  9:28 ` gasper.azman at gmail dot com
2023-09-02  8:54 ` waffl3x at protonmail dot com
2023-09-02 22:30 ` gasper.azman at gmail dot com
2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
2024-01-09 21:56 ` cvs-commit at gcc dot gnu.org
2024-01-09 21:57 ` cvs-commit at gcc dot gnu.org
2024-01-11 20:47 ` corentinjabot at gmail dot com
2024-01-11 21:08 ` waffl3x at protonmail dot com
2024-01-11 22:00 ` gasper.azman at gmail dot com
2024-01-11 22:01 ` jakub at gcc dot gnu.org
2024-01-12  0:26 ` waffl3x at protonmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).