Consider this code: -------------------- #include <iostream> struct null { null() {} template<class T> operator T*() const { return 0; } template<class C, class T> operator T C::*() const { return 0; } private: null(const null&); null& operator=(const null&); void operator&() const; }; static struct null null; int main() { int* ptr = null; std::cout << (ptr == null) << ", " << (ptr != null); return 0; } -------------------------------- This compiles and gives the expected output ("true, false") on the following platforms: http://codepad.org (GCC 4.1, Linux) Ubuntu 9.10, GCC 4.3 Ubuntu 10.04, GCC 4.4 Mac OS X 10.6, GCC 4.2 Mac OS X 10.6, GCC 4.4 Cygwin, GCC 4.3 Cygwin, GCC 4.4 Unknown Linux variant, Clang 2.8 (trunk 111679) (the "clang" bot on irc.freenode.net) However, I get following error on these platforms ------------- error: no match for 'operator==' in 'ptr == null' ------------- Cygwin, GCC 4.5 Ubuntu 10.04, GCC 4.5 Unknown Linux variant, GCC 4.6.0 20100507 (the "geordi" bot on irc.freenode.net) The people in the irc.freenode.net/##c++ channel confirm that this is indeed valid C++ code and therefore a bug in GCC. I do not have ready access to some of these systems (anymore), so I can not say with certainity what their host, target, or build triplets are.
The summary seems backwards: the conversion shouldn't generate operator==, instead using operator== should trigger the conversion, but fails to when the conversion operator is a template. Strangely, adding a non-template conversion operator causes template argument deduction to succeed, even though the non-template operator isn't used e.g. #include <iostream> struct null { null() {} template<class T> operator T*() const { return 0; } template<class C, class T> operator T C::*() const { return 0; } private: operator double*() const; // ??? null(const null&); null& operator=(const null&); void operator&() const; }; static struct null null; int main() { int* ptr = null; std::cout << (ptr == null) << ", " << (ptr != null); return 0; }
It is caused by revision 155415: http://gcc.gnu.org/ml/gcc-cvs/2009-12/msg00559.html
I'd just like to confirm this bug on Fedora 14 (gcc (GCC) 4.5.1 20100924) which is currently preventing me from compiling a large 3D graphics commercial library.
A candidate fix has been proposed at http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01129.html
Author: dodji Date: Mon Nov 29 16:30:54 2010 New Revision: 167248 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167248 Log: Fix PR c++/45383 Reverting the fix for PR c++/42260 fixes c++/45383. This reverts commit r155415. gcc/cp/ Reverted patch for PR c++/42260 * cp-tree.h (lookup_conversions): Reverted "Add new bool parameter to declarationE." * search.c (lookup_conversion): Reverted "Use new bool parameter in definition". * call.c (add_builtin_candidates): Reverted "Don't lookup template conversion" (convert_class_to_reference, build_user_type_conversion_1, build_op_call): Reverted "Adjust". * cvt.c (build_expr_type_conversion): Reverted "Likewise". gcc/testsuite/ Reverted patch for PR c++/42260 * conversion/cast2.C: Reverted New test. Removed: trunk/gcc/testsuite/g++.dg/conversion/cast2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/cp-tree.h trunk/gcc/cp/cvt.c trunk/gcc/cp/search.c trunk/gcc/testsuite/ChangeLog
Author: dodji Date: Mon Nov 29 16:31:40 2010 New Revision: 167250 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167250 Log: Fix PR c++/42260 and ensure PR c++/45383 is fixed gcc/cp/ c++/42260 * call.c (add_builtin_candidate): At this point the resulting type of an indirection operator should be complete. gcc/testsuite/ c++/42260 c++/45383 * g++.dg/conversion/cast2.C: New test. * g++.dg/conversion/cond4/C: Likewise. Ensures we don't regress on PR c++/45383 Added: trunk/gcc/testsuite/g++.dg/conversion/cast2.C trunk/gcc/testsuite/g++.dg/conversion/cond4.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog
GCC 4.5.2 is being released, adjusting target milestone.
Fixed in 4.6
Is this still broken in 4.5?
Yes.
Dodji, is there any reason not to apply this fix to 4.5 as well?
> Dodji, is there any reason not to apply this fix to 4.5 as well? I was waiting to see how the initial fix would behave in 4.6 and it felt below my radar. But then PR c++/46824 hinted for a better fix for this issue. So I am backporting the revert of PR c++/42260 and the fix of PR c++/46824 instead. I have tested it on x86_64-unknown-linux-gnu aginst 4.5
I have committed those in 4.5 and the changes can be browsed at http://gcc.gnu.org/git/?p=gcc.git;a=commit;h=eb9cc5c6f and http://gcc.gnu.org/git/?p=gcc.git;a=commit;h=9912b04c
*sigh*, 2nd commit while the 4.5 branch is frozen ...
GCC 4.5.3 is being released, adjusting target milestone.
Fixed in 4.5.3.