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

            Bug ID: 122383
           Summary: auto deduction fails when initializing from a template
                    conversion operator address
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: attackerj1113 at gmail dot com
  Target Milestone: ---

Consider the following code:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
template<class T> struct X {
  template<class U> operator X<U>(); 
};

struct A {};
struct B {};

void test() {
    auto (X<A>::*pf)() = &X<A>::operator X<B>;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

GCC rejects this, but other major compilers (Clang, MSVC, EDG) accept the code
as valid.

GCC output:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<source>: In function 'void test()':
<source>:9:26: error: unable to deduce 'auto (X<A>::*)()' from '&
X<A>::operator X<U>'
    9 |     auto (X<A>::*pf)() = &X<A>::operator X<B>;
<source>:9:42: note:   couldn't deduce template parameter 'auto'
    9 |     auto (X<A>::*pf)() = &X<A>::operator X<B>;
      |                                          ^~~~
Compiler returned: 1

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See godbolt: https://godbolt.org/z/nsc9394Kh

I believe auto can be easily deduced here as X<B> (X<A>::*)().


If written as:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
auto pf = &X<A>::operator X<B>;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In that case, 'auto' should likewise deduce to 'X<B> (X<A>::*)()'.

It seems that GCC perhaps attempts template parameter deduction inside the
member conversion operator template, rather than deducing the 'auto' type
directly from the initializer’s full type.

Reply via email to