// { dg-do compile } template<typename T> struct A; template<typename T> struct B {}; template<typename T> A<T>& operator<<(A<T>&, const B<T>&); template<typename T> struct A { A<T>& operator<<(A<T>& (*)(A<T>&)); }; template<typename T> A<T>& foo(A<T>&); extern A<char> c; int main() { c << (1, foo); } ICEs in resolve_overloaded_unification with 3.4, 4.1.2 and the trunk, compiles fine with 3.2.3.
Confirmed.
Subject: Bug 32232 Author: mmitchel Date: Sat Jul 7 07:31:54 2007 New Revision: 126435 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126435 Log: PR c++/32232 * pt.c (resolve_overloaded_unification): Robustify. Return a bool, not an int. (type_unification_real): Adjust accordingly. PR c++/32232 * g++.dg/template/overload9.C: New test. Added: trunk/gcc/testsuite/g++.dg/template/overload9.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/pt.c trunk/gcc/testsuite/ChangeLog
Fixed in 4.3.0.
Subject: Bug 32232 Author: mmitchel Date: Sat Jul 7 19:16:09 2007 New Revision: 126443 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=126443 Log: PR c++/32232 * pt.c (resolve_overloaded_unification): Robustify. Return a bool, not an int. (type_unification_real): Adjust accordingly. PR c++/32232 * g++.dg/template/overload9.C: New test. Added: branches/gcc-4_2-branch/gcc/testsuite/g++.dg/template/overload9.C Modified: branches/gcc-4_2-branch/gcc/cp/ChangeLog branches/gcc-4_2-branch/gcc/cp/pt.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
Fixed in 4.2.1.
Mark, I don't think the fix for this PR is complete, because the following simplified testcase (which previously ICE'd) should compile IMHO: ============================================================= template<typename> struct A { A& operator<<(void (*)(A&)); }; template<typename T> A<T>& operator<<(A<T>&, const A<T>&); template<typename T> void foo(A<T>&); void bar() { A<int>() << (1, foo<int>); } ============================================================= But it is rejected with the following error message: bug.cc: In function 'void bar()': bug.cc:12: error: no match for 'operator<<' in 'A<int>() << (0, foo<int>)' bug.cc:3: note: candidates are: A< <template-parameter-1-1> >& A< <template-parameter-1-1> >::operator<<(void (*)(A< <template-parameter-1-1> >&)) [with <template-parameter-1-1> = int] An even smaller testcase for this problem is the following: ============================================================= struct A { A& operator<<(void (*)(A&)); }; template<typename> void foo(A&); void bar() { A() << (1, foo<int>); } ============================================================= bug.cc: In function 'void bar()': bug.cc:10: error: no match for 'operator<<' in 'A() << (0, foo<int>)' bug.cc:3: note: candidates are: A& A::operator<<(void (*)(A&)) The code compiles fine, if I remove the "0,". Btw, there's another glitch in the error message: The code contains "(1, foo<int>)", which is printed as "(0, foo<int>)" in the error message.
Subject: Re: [4.1 Regression] ICE in resolve_overloaded_unification reichelt at gcc dot gnu dot org wrote: > template<typename> struct A > { > A& operator<<(void (*)(A&)); > }; > > template<typename T> A<T>& operator<<(A<T>&, const A<T>&); > > template<typename T> void foo(A<T>&); > > void bar() > { > A<int>() << (1, foo<int>); > } As I (thought I? meant to?) said in the patch submission mail, I don't think this is valid. The syntactic form of the expression matters for deduction purposes, and my reading of the standard is that only a (generalized) identifier is allowed. (It's not very clear, but I didn't see anything to suggest that your code was valid.) The version of the EDG front end I had on hand agreed with me. :-) You could certainly ask on the core reflector, etc. The issue about printing "(0, ...)" instead of "(1, ...)" is certainly a bug, but a different one from this.
Closing 4.1 branch.