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.