Bug 32232 - [4.1 Regression] ICE in resolve_overloaded_unification
Summary: [4.1 Regression] ICE in resolve_overloaded_unification
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.2
: P1 normal
Target Milestone: 4.2.1
Assignee: Not yet assigned to anyone
URL:
Keywords: ice-on-valid-code, monitored
Depends on:
Blocks:
 
Reported: 2007-06-06 10:33 UTC by Jakub Jelinek
Modified: 2008-07-04 16:07 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work: 3.3.6 4.2.0 4.3.0
Known to fail: 3.4.0 4.1.2 4.1.3
Last reconfirmed: 2007-07-06 02:56:28


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2007-06-06 10:33:11 UTC
// { 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.
Comment 1 Richard Biener 2007-06-06 12:55:38 UTC
Confirmed.
Comment 2 Mark Mitchell 2007-07-07 07:32:09 UTC
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

Comment 3 Mark Mitchell 2007-07-07 07:36:07 UTC
Fixed in 4.3.0.
Comment 4 Mark Mitchell 2007-07-07 19:16:19 UTC
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

Comment 5 Mark Mitchell 2007-07-07 19:16:38 UTC
Fixed in 4.2.1.
Comment 6 Volker Reichelt 2007-07-11 23:04:33 UTC
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.
Comment 7 Mark Mitchell 2007-07-12 06:20:13 UTC
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.

Comment 8 Joseph S. Myers 2008-07-04 16:07:35 UTC
Closing 4.1 branch.