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

            Bug ID: 100385
           Summary: overload resolution for function call expression on
                    object selects `operator auto` conversion candidate.
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mizvekov at gmail dot com
  Target Milestone: ---

The following program compiles successfully, but should be rejected:
```
template<auto V> struct constant {
    constexpr operator auto () const noexcept { return V; }
};

void myfree(void*);

void test() {
    constant<myfree>{}(nullptr);
}
```
According to `[over.call.object]/2`:
```
..., and where conversion-type-id denotes the type “pointer to function of
(P1,…,Pn) returning R”, or the type “reference to pointer to function of
(P1,…,Pn) returning R”, or the type “reference to function of (P1,…,Pn)
returning R”, a surrogate call function with the unique name call-function and
having the form
R call-function ( conversion-type-id  F, P1 a1, …, Pn an) { return F (a1, …,
an); }
is also considered as a candidate function.
...
```
But here `auto` is neither pointer, reference, nor reference to pointer to
function. So I think the GCC behavior here is non-conformant, though it does
look useful to accept it.

Here is a workspace showing that Clang and MSVC reject this:
https://godbolt.org/z/aT6TrPz1h

The above workspace also is a double whammy in that it shows that libstdc++'s
unique_ptr implementation somehow hides this problem from Clang.

Reply via email to