command: g++-4 -v -save-temps -c lookup-bug.cc keywords: rejects-valid expecting: (success) program output: Using built-in specs. Target: powerpc-apple-darwin7 Configured with: ../configure --prefix=/sw --prefix=/sw/lib/gcc4 --enable-languages=c,c++,f95,objc,java --infodir=/share/info --with-gmp=/sw --with-included-gettext --host=powerpc-apple-darwin7 --with-as=/sw/lib/odcctools/bin/as --with-ld=/sw/lib/odcctools/bin/ld Thread model: posix gcc version 4.0.2 /sw/lib/gcc4/libexec/gcc/powerpc-apple-darwin7/4.0.2/cc1plus -E -quiet -v -D__DYNAMIC__ -D__APPLE_CC__=1 lookup-bug.cc -fPIC -fpch-preprocess -o lookup-bug.ii ignoring nonexistent directory "/sw/lib/gcc4/lib/gcc/powerpc-apple-darwin7/4.0.2/../../../../powerpc-apple-darwin7/include" #include "..." search starts here: #include <...> search starts here: /sw/lib/gcc4/lib/gcc/powerpc-apple-darwin7/4.0.2/../../../../include/c++/4.0.2 /sw/lib/gcc4/lib/gcc/powerpc-apple-darwin7/4.0.2/../../../../include/c++/4.0.2/powerpc-apple-darwin7 /sw/lib/gcc4/lib/gcc/powerpc-apple-darwin7/4.0.2/../../../../include/c++/4.0.2/backward /usr/local/include /sw/lib/gcc4/include /sw/lib/gcc4/lib/gcc/powerpc-apple-darwin7/4.0.2/include /usr/include /System/Library/Frameworks /Library/Frameworks End of search list. /sw/lib/gcc4/libexec/gcc/powerpc-apple-darwin7/4.0.2/cc1plus -fpreprocessed lookup-bug.ii -fPIC -quiet -dumpbase lookup-bug.cc -auxbase lookup-bug -version -o lookup-bug.s GNU C++ version 4.0.2 (powerpc-apple-darwin7) compiled by GNU C version 3.3 20030304 (Apple Computer, Inc. build 1640). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 lookup-bug.cc: In member function 'std::ostream& foo::name_space::dump(std::ostream&) const': lookup-bug.cc:249: error: no matching function for call to 'mem_fun(std::ostream& (foo::instance_collection_base::*)(std::ostream&)const, const util::memory::never_ptr<const foo::instance_collection_base>&)' known to work: gcc-4.0.1 (built likewise) remarks: Note that this is not std::mem_fun, but rather, a custom extension for pointer-classes, defined in namespace util. In the attached .ii, changing the static member declaration: static const never_ptr<const instance_collection_base> null; to static const never_ptr<instance_collection_base> null; is sufficient to compile successfully.
Created attachment 9912 [details] test case triggering bug
Here is the reduced testcase: template <class R, template <class> class P, class T, class A> inline int mem_fun(R (T::*f)(A), const P<T>& null) {} template <class T> class never_ptr {}; struct instance_collection_base { int& pair_dump(int&) const; static const never_ptr<const instance_collection_base> null; }; int& dump(int& o) { mem_fun(&instance_collection_base::pair_dump, instance_collection_base::null); } But I think this is invalid as "const instance_collection_base" is not the same as instance_collection_base. so T cannot be matched to "const instance_collection_base" as it was before 4.1.0/4.0.2. ICC and Comeau rejects the same code too for the same reason.
Subject: Re: [4.0 regression] lookup fails to match to function call, const-sensitive > ------- Comment #2 from pinskia at gcc dot gnu dot org 2005-10-06 19:48 ------- > Here is the reduced testcase: > template <class R, template <class> class P, class T, class A> > inline int mem_fun(R (T::*f)(A), const P<T>& null) {} > > template <class T> class never_ptr {}; > > struct instance_collection_base { > int& pair_dump(int&) const; > static const never_ptr<const instance_collection_base> null; > }; > > int& dump(int& o) { > mem_fun(&instance_collection_base::pair_dump, > instance_collection_base::null); > } > > But I think this is invalid as "const instance_collection_base" is not > the same as instance_collection_base. so T cannot be matched to > "const instance_collection_base" as it was before 4.1.0/4.0.2. > > ICC and Comeau rejects the same code too for the same reason. True, const T != T, but shouldn't const-volatile qualifiers be disregarded when trying to match member functions of T? Perhaps irrelevant, but in the context of my test-case I wanted to be precise about member-function constness.
Subject: Re: [4.0 regression] lookup fails to match to function call, const-sensitive Something else puzzling to me, that I noticed from your reduction: Why is the compiler always matching the non-const version of mem_fun, when the member-function I'm passing in (pair_dump) is const? Isn't the const a closer match? In fact, if I remove the non-const mem_fun() definition, then I get "no match found" from g++-3.3 to 4.0 -- doesn't even accept the const version. I've seen some old PRs on this matter, but don't recall what their resolution was. > mem_fun(&instance_collection_base::pair_dump, > instance_collection_base::null); // prefers this: template <class R, template <class> class P, class T, class A> inline mem_fun1_p_t<R, P, T, A> mem_fun(R (T::*f)(A), const P<T>& null) { return mem_fun1_p_t<R, P, T, A>(f); } // over this: template <class R, template <class> class P, class T, class A> inline const_mem_fun1_p_t<R, P, T, A> mem_fun(R (T::*f)(A) const, const P<T>& null) { return const_mem_fun1_p_t<R, P, T, A>(f); }
I have seen this issue one time and the solution is to cast the argument to memfun to the appropriate type - f.i. the const member function, or to specify the template parameters to memfun. In case you have both const and non-const member functions you'll have an ambiguous match otherwise. This really is invalid.
I now second your opinions that this is invalid. Upon closer examination, what I *should've* written to make this code valid is the following: template <class R, template <class> class P, class T, class A> inline const_mem_fun1_p_t<R, P, T, A> mem_fun(R (T::*f)(A) const, const P<const T>& null) { return const_mem_fun1_p_t<R, P, T, A>(f); } To be more correct, I changed "const P<T>" to "const P<const T>" in the function parameter list. Now gcc-3.3 to 4.0.x find the right match and accept it. (So really, the previous versions 'accepts-invalid.') Thanks for being patient with me on this.
Created attachment 9913 [details] corrected header file Just as a follow-up, here's what the new valid header file looks like, with all the various mem_fun definitions corrected in the const cases. (Perhaps this might be useful for reference in future test cases?)
Housekeeping: re-classify as invalid? I wasn't able to find an "accepts-invalid" version of this bug in the database for reference. That bug would've been fixed sometime between 4.0.1 and 4.0.2.
Submitter agrees code is invalid.