Bug 4672 - [4.0 only] [DR 214] Template parameter deduction fails for overloaded template functions.
Summary: [4.0 only] [DR 214] Template parameter deduction fails for overloaded templat...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.0
: P3 normal
Target Milestone: 4.0.1
Assignee: Nathan Sidwell
URL:
Keywords: rejects-valid
: 11338 (view as bug list)
Depends on: 19203
Blocks: 15011
  Show dependency treegraph
 
Reported: 2001-10-25 16:26 UTC by sven
Modified: 2005-06-02 09:39 UTC (History)
6 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail: 3.4.1 4.0.0
Last reconfirmed: 2005-01-06 01:48:50


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description sven 2001-10-25 16:26:12 UTC
This works fine with GCC 2.95.1 but not with 2.96 or 3.0.

We have also compared this code with the Comeau C/C++ 4.2.45.2
compiler for a third oppinion. It accepts the code without any
errors.

The problem is with template parameter deduction when there are two
overloaded template functions. One is taking a reference and the other
pointer. 

//Code example:
// checked_cast is intended to work as static_cast but for debug
// builds it will check that the cast is correct.

template<class T, class U> inline T checked_cast(U & from)
{
  try
  {
    dynamic_cast <T> (from);
  }
  catch (...)
  {
    // Error
  }
  return static_cast<T>(from);
}

template <class T, class U> inline T checked_cast(U * from)
{
  if (! dynamic_cast <T>(from))
  {
    // Error
  }
  return static_cast <T>(from);
}

class A
{
public:
  virtual ~A();
};

class C;

class B : public A
{
  void foo () const;
};

class C : public B
{
};

void B::foo () const
{
  C const & c1 = checked_cast <C const &> (*this);
  C const * c2 = checked_cast <C const *> (this);
}

Output from g++ (3.0)

/usr/local/bin/new-fronts/g++ -v input.cc
Reading specs from /usr/local/bin/new-fronts/../lib/gcc-lib/i686-pc-linux-gnu/3.0/specs
Configured with: ./configure 
Thread model: single
gcc version 3.0
GNU CPP version 3.0 (cpplib) (i386 Linux/ELF)
GNU C++ version 3.0 (i686-pc-linux-gnu)
 compiled by GNU C version 3.0.
ignoring duplicate directory "/usr/local/include/g++-v3"
ignoring duplicate directory "/usr/local/include/g++-v3/i686-pc-linux-gnu"
ignoring duplicate directory "/usr/local/include/g++-v3/backward"
ignoring duplicate directory "/usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.0/include"
ignoring duplicate directory "/usr/local/i686-pc-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/bin/lib/../include/g++-v3
 /usr/local/bin/lib/../include/g++-v3/i686-pc-linux-gnu
 /usr/local/bin/lib/../include/g++-v3/backward
 /usr/local/bin/lib/gcc-lib/i686-pc-linux-gnu/3.0/include
 /usr/local/bin/lib/../i686-pc-linux-gnu/include
 /usr/local/include
 /usr/include
End of search list.
input.cc: In member function `void B::foo() const':
input.cc:44: call of overloaded `U_checked_cast(const B* const)' is ambiguous
input.cc:2: candidates are: T U_checked_cast(U&) [with T = const C*, U = const 
   B* const]
input.cc:15:                 T U_checked_cast(U*) [with T = const C*, U = const 
   B]

Output from g++ (2.95.1)

g++ -v input.cc
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/specs
gcc driver version 2.95.2 19991024 (release) executing gcc version 2.95.1
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/cpp -lang-c++ -v -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__EXCEPTIONS -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -Di686 -Dpentiumpro -D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__ input.cc /tmp/ccNhfq7X.ii
GNU CPP version 2.95.1 19990816 (release) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/../../../../include/g++-3
 /usr/local/include
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/../../../../i686-pc-linux-gnu/include
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
End of omitted list.
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/cc1plus /tmp/ccNhfq7X.ii -quiet -dumpbase input.cc -version -o /tmp/ccSDYmSL.s
GNU C++ version 2.95.1 19990816 (release) (i686-pc-linux-gnu) compiled by GNU C version 2.95.1 19990816 (release).
 as -V -Qy -o /tmp/cc1jJrLA.o /tmp/ccSDYmSL.s
[snip]

Release:
3.0

Environment:
System: Linux harold.prqa.ie 2.2.14-6.1.1smp #1 SMP Thu Apr 13 19:55:55 EDT 2000 i686 unknown
Architecture: i686
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: ./configure
Comment 1 sven 2001-10-25 16:26:12 UTC
Fix:
The workaround we use is to specify two parameters to checked_cast.
This works but does not look as nice as it is intended to tod.
Comment 2 Kriang Lerdsuwanakij 2001-10-27 04:45:45 UTC
State-Changed-From-To: open->analyzed
State-Changed-Why: Confirm as a bug.
Comment 3 Nathan Sidwell 2001-12-29 08:31:32 UTC
Responsible-Changed-From-To: unassigned->nathan
Responsible-Changed-Why: patch in progress
Comment 4 Giovanni Bajo 2003-04-10 05:02:10 UTC
From: "Giovanni Bajo" <giovannibajo@libero.it>
To: <gcc-gnats@gcc.gnu.org>,
	<sven@programmingresearch.ie>,
	<gcc-bugs@gcc.gnu.org>,
	<nathan@gcc.gnu.org>,
	<gcc-prs@gcc.gnu.org>
Cc: "Wolfgang Bangerth" <bangerth@ices.utexas.edu>
Subject: Re: c++/4672: [2003-01-03]Template parameter deduction fails for overloaded template functions.
Date: Thu, 10 Apr 2003 05:02:10 +0200

 http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p
 r=4672
 
 This is a 3.2/3.3 regression with respect to 2.95, where the code compiled
 correctly. Redux is:
 
 -------------------------------------------------------------
 template<class T, class U> inline void Foo(U & from) {}
 template<class T, class U> inline void Foo(U * from) {}
 
 struct A
 {
   void foo () const
   {
    Foo<int>(this);
   }
 };
 -------------------------------------------------------------
 pr4672.cpp: In member function `void A::foo() const':
 pr4672.cpp:8: error: call of overloaded `Foo(const A* const)' is ambiguous
 pr4672.cpp:1: error: candidates are: void Foo(U&) [with T = int, U = const
 A* const]
 pr4672.cpp:2: error:                 void Foo(U*) [with T = int, U = const
 A]
 
 Notice that if you remove the (useless) template paramater T from Foo(), the
 code compiles correctly. I would flag this regression as quite serious, too.
 Please, somebody check it on 3.4 and see if it's still present (mainline is
 still broken for cygwin).
 
 Giovanni Bajo
 

Comment 5 Wolfgang Bangerth 2003-04-10 09:01:17 UTC
From: Wolfgang Bangerth <bangerth@ices.utexas.edu>
To: Giovanni Bajo <giovannibajo@libero.it>
Cc: gcc-gnats@gcc.gnu.org, <sven@programmingresearch.ie>,
   <gcc-bugs@gcc.gnu.org>, <nathan@gcc.gnu.org>
Subject: Re: c++/4672: [2003-01-03]Template parameter deduction fails for
 overloaded template functions.
Date: Thu, 10 Apr 2003 09:01:17 -0500 (CDT)

 > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=4672
 > 
 > This is a 3.2/3.3 regression with respect to 2.95, where the code compiled
 > correctly. Redux is:
 
 Indeed, this is a regression in 3.2/3.3/3.4 introduced between 2.95 and 
 3.0. I bumped the priority and adjusted the synopsis.
 W.
 
 
 > -------------------------------------------------------------
 > template<class T, class U> inline void Foo(U & from) {}
 > template<class T, class U> inline void Foo(U * from) {}
 > 
 > struct A
 > {
 >   void foo () const
 >   {
 >    Foo<int>(this);
 >   }
 > };
 > -------------------------------------------------------------
 > pr4672.cpp: In member function `void A::foo() const':
 > pr4672.cpp:8: error: call of overloaded `Foo(const A* const)' is ambiguous
 > pr4672.cpp:1: error: candidates are: void Foo(U&) [with T = int, U = const A* const]
 > pr4672.cpp:2: error:                 void Foo(U*) [with T = int, U = const A]
 
 -------------------------------------------------------------------------
 Wolfgang Bangerth              email:            bangerth@ices.utexas.edu
                                www: http://www.ices.utexas.edu/~bangerth/
Comment 6 Andrew Pinski 2003-06-02 16:40:24 UTC
still exists on the mainline (20030529) and 3.3.1 (20030526):

pr4672.cc: In member function `void A::foo() const':
pr4672.cc:8: error: call of overloaded `Foo(const A* const)' is ambiguous
pr4672.cc:1: note: candidates are: void Foo(U&) [with T = int, U = const A* 
   const]
pr4672.cc:2: note:                 void Foo(U*) [with T = int, U = const A]
Comment 7 Wolfgang Bangerth 2003-06-26 22:06:42 UTC
*** Bug 11338 has been marked as a duplicate of this bug. ***
Comment 8 Nathan Sidwell 2003-07-07 09:18:35 UTC
This will not be fixed in 3.3.
3.3 is doing what the std says. DR 214 is in ready status -- not
yet accepted as a DR.
Comment 9 Giovanni Bajo 2003-07-07 09:40:48 UTC
Ok, I suspend the bug until the defect report is accepted.
Comment 10 Giovanni Bajo 2004-02-03 13:31:14 UTC
The DR is now in WP status, and (as far as I can tell) it does say that GCC is 
wrong. 2.95 worked as expected so we have a regression. Nathan, do you confirm?
Comment 11 Giovanni Bajo 2004-06-06 03:35:31 UTC
Retargeting to 3.4.1, being a regression on that release branch.
Comment 12 Mark Mitchell 2004-06-21 21:27:02 UTC
Postponed until GCC 3.4.2.
Comment 13 Mark Mitchell 2004-08-29 18:43:09 UTC
Postponed until GCC 3.4.3.
Comment 14 Giovanni Bajo 2004-10-07 00:34:01 UTC
Notice that there is a general agreement that we should not implement WP 
defects within the default C++ dialect, especially when we are doing the 
correct thing wrt C++98. So we can keep this open, but will have to be 
implemented in the C++0x dialect. To the best of my understanding, we are 
strictly following C++98.

I'm thus removing the regression mark and the milestone from this bug.
Comment 15 Andrew Pinski 2005-04-07 07:04:27 UTC
This was fixed on the mainline by the patch for PR 19203.
Comment 16 Nathan Sidwell 2005-06-02 09:39:26 UTC
The test cases compile without error on 4_0 branch