enum Relation {equalOp}; template<typename B> class A { public: static bool Relop(const A&, const A&, Relation); friend bool operator==(const A& a1, const A& a2) { return Relop(a1, a2, equalOp); } B* b; }; int main() { A<int> a; a == a; return 0; } produces: foo.cc: In function `bool operator==(const A<int>&, const A<int>&)': foo.cc:16: instantiated from here foo.cc:10: error: no matching function for call to `A<B>::Relop(const A<int>&, const A<int>&, Relation)' foo.cc:6: note: candidates are: static bool A<B>::Relop(const A<B>&, const A<B>&, Relation) Even if this code is actually invalid (who could tell except the committee?) the error message should at least indicate what is really wrong. Ivan
Confirmed, a regression, this is template related.
Here is something slightly smaller: ------------------- template <typename T> struct S { static void foo(const S&); friend void bar(const S& s) { foo(s); } }; int main() { S<int> a; bar(a); } ------------------ Although all prior versions of gcc before 3.4 and icc in strict mode accept this code, I am a little puzzled why this is so: bar() is just a friend, not a member, why should it look inside struct S to find the static function? Why don't I have to qualify foo as S::foo? Alas, that isn't the problem, from the error message gcc gives, it is pretty obvious that gcc just gets somehow confused about templates in this case. W.
Working on a fix.
This code is invalid; according to the standard, the friend function should not be injected into the namespace scope. (This is a change from the ARM.) However, g++ has always done the injection, and we have not yet removed that functionality, so this code should work as expected. The standard-conforming way of doing this is to have a namespace-scope declaration of the function. You can still define it in the class, but it should be declared outside the class. This comment is meant to answer Wolfgang's question regarding this seems to work at all.
Subject: Bug 15625 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: mmitchel@gcc.gnu.org 2004-05-31 21:04:15 Modified files: gcc/testsuite : ChangeLog gcc/cp : ChangeLog call.c cp-tree.h cvt.c name-lookup.c pt.c tree.c typeck.c gcc/testsuite/g++.dg/ext: packed3.C packed4.C gcc/testsuite/g++.dg/template: friend.C Added files: gcc/testsuite/g++.dg/expr: ptrmem5.C gcc/testsuite/g++.dg/ext: packed6.C gcc/testsuite/g++.dg/template: friend27.C friend28.C gcc/testsuite/g++.dg/warn: Wreturn-1.C Log message: PR c++/15742 * call.c (build_over_call): Set current_function_returns_abnormally even in template functions. PR c++/15696 * cp-tree.h (invalid_nonstatic_memfn_p): New function. * cvt.c (convert_to_void): Use it. * typeck.c (invalid_nonstatic_memfn_p): New function. (decay_conversion): Use it. PR c++/15625 * pt.c (tsubst_decl): Set DECL_FRIEND_CONTEXT for instantiated templates. PR c++/15629 * name-lookup.c (arg_assoc_class): Do not find template specializations. PR c++/15209 * tree.c (lvalue_p_1): Only consider the right-hand side of "." expressions when determining whether or not an express is packed. PR c++/15742 * g++.dg/warn/Wreturn-1.C: New test. PR c++/15696 * g++.dg/expr/ptrmem5.C: New test. PR c++/15625 * g++.dg/template/friend27.C: New test. PR c++/15629 * g++.dg/template/friend28.C: New test. * g++.dg/template/friend.C: Do not depend on <iostream>. Add error message. PR c++/15209 * g++.dg/ext/packed3.C: Remove bogus error. * g++.dg/ext/packed4.C: Remove bogus check. * g++.dg/ext/packed6.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.187&r2=1.3389.2.188 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3892.2.109&r2=1.3892.2.110 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.452.2.16&r2=1.452.2.17 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.946.4.12&r2=1.946.4.13 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cvt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.151.4.1&r2=1.151.4.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.34.2.13&r2=1.34.2.14 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.816.2.26&r2=1.816.2.27 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/tree.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.360.4.5&r2=1.360.4.6 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.519.2.18&r2=1.519.2.19 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/ptrmem5.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed6.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed3.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1&r2=1.1.24.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed4.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.1&r2=1.1.24.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend27.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend28.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.5&r2=1.5.56.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/warn/Wreturn-1.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
Subject: Bug 15625 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2004-05-31 21:24:31 Modified files: gcc/cp : call.c cp-tree.h cvt.c name-lookup.c pt.c tree.c typeck.c gcc/testsuite/g++.dg/ext: packed3.C packed4.C gcc/testsuite/g++.dg/template: friend.C Added files: gcc/testsuite/g++.dg/expr: ptrmem5.C gcc/testsuite/g++.dg/ext: packed6.C gcc/testsuite/g++.dg/template: friend27.C friend28.C gcc/testsuite/g++.dg/warn: Wreturn-1.C Log message: PR c++/15742 * call.c (build_over_call): Set current_function_returns_abnormally even in template functions. PR c++/15696 * cp-tree.h (invalid_nonstatic_memfn_p): New function. * cvt.c (convert_to_void): Use it. * typeck.c (invalid_nonstatic_memfn_p): New function. (decay_conversion): Use it. PR c++/15625 * pt.c (tsubst_decl): Set DECL_FRIEND_CONTEXT for instantiated templates. PR c++/15629 * name-lookup.c (arg_assoc_class): Do not find template specializations. PR c++/15209 * tree.c (lvalue_p_1): Only consider the right-hand side of "." expressions when determining whether or not an express is packed. PR c++/15742 * g++.dg/warn/Wreturn-1.C: New test. PR c++/15696 * g++.dg/expr/ptrmem5.C: New test. PR c++/15625 * g++.dg/template/friend27.C: New test. PR c++/15629 * g++.dg/template/friend28.C: New test. * g++.dg/template/friend.C: Do not depend on <iostream>. Add error message. PR c++/15209 * g++.dg/ext/packed3.C: Remove bogus error. * g++.dg/ext/packed4.C: Remove bogus check. * g++.dg/ext/packed6.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&r1=1.476&r2=1.477 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&r1=1.969&r2=1.970 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cvt.c.diff?cvsroot=gcc&r1=1.156&r2=1.157 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&r1=1.56&r2=1.57 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.856&r2=1.857 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/tree.c.diff?cvsroot=gcc&r1=1.374&r2=1.375 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&r1=1.547&r2=1.548 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/ptrmem5.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed6.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed3.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/ext/packed4.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend27.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend28.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend.C.diff?cvsroot=gcc&r1=1.5&r2=1.6 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/warn/Wreturn-1.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
Fixed in GCC 3.4.1.