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

Patrick Palka <ppalka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Two conversion operators    |member function
                   |that differ only in         |template-head requirements
                   |constraints cause ICE with  |not included in mangling
                   |checking                    |

--- Comment #2 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Patrick Palka from comment #1)
> Seems we're neglecting to mangle constraints on user-defined conversion
> functions, leading to the logically distinct conversion functions having the
> same same mangling.  Clang mangles the constrained one as
> _ZNK1ScvT_IiQ11always_trueIS0_EEEv.
This bug actually seems to be more general: we don't include template-head
requirements of member functions at all, only their trailing requirements:

template<typename T> concept always_true = true;

template<class T> static void foo() { }
template<class T> requires always_true<T> static void foo() { }

template<class T> static void bar() { }
template<class T> static void bar() requires always_true<T> { }

struct B {
  template<class T> static void foo() { }
  template<class T> requires always_true<T> static void foo() { }

  template<class T> static void bar() { }
  template<class T> static void bar() requires always_true<T> { }
};

int main(){
  foo<int>(); // _Z3fooIiQ11always_trueIT_EEvv
  bar<int>(); // _Z3barIiEvvQ11always_trueIT_E
  B::foo<int>(); // _ZN1B3fooIiEEvv  ???
  B::bar<int>(); // _ZN1B3barIiEEvvQ11always_trueIT_E
}


So a workaround for your testcase is to use a trailing-requirement:

    template<typename T>explicit operator T() requires always_true<T>

Reply via email to