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
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.
State-Changed-From-To: open->analyzed State-Changed-Why: Confirm as a bug.
Responsible-Changed-From-To: unassigned->nathan Responsible-Changed-Why: patch in progress
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
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/
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]
*** Bug 11338 has been marked as a duplicate of this bug. ***
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.
Ok, I suspend the bug until the defect report is accepted.
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?
Retargeting to 3.4.1, being a regression on that release branch.
Postponed until GCC 3.4.2.
Postponed until GCC 3.4.3.
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.
This was fixed on the mainline by the patch for PR 19203.
The test cases compile without error on 4_0 branch