Results from the command line: bash-2.05a$ gcc -v -save-temps Test-2.cpp Reading specs from /usr/libexec/gcc/darwin/ppc/3.3/specs Thread model: posix gcc version 3.3 20030304 (Apple Computer, Inc. build 1435) /usr/libexec/gcc/darwin/ppc/3.3/cc1plus -E -D__GNUG__=3 -quiet -v -D__GNUC__=3 - D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=0 -D__APPLE_CC__=1435 -D__DYNAMIC__ Test-2.cpp -fPIC -D__private_extern__=extern Test-2.ii ignoring nonexistent directory "/usr/ppc-darwin/include" ignoring nonexistent directory "/Local/Library/Frameworks" #include "..." search starts here: #include <...> search starts here: /usr/include/gcc/darwin/3.3/c++ /usr/include/gcc/darwin/3.3/c++/ppc-darwin /usr/include/gcc/darwin/3.3/c++/backward /usr/local/include /usr/include/gcc/darwin/3.3 /usr/include End of search list. Framework search starts here: /System/Library/Frameworks /Library/Frameworks End of framework search list. /usr/libexec/gcc/darwin/ppc/3.3/cc1plus -fpreprocessed Test-2.ii -fPIC -quiet -dumpbase Test-2.cpp -auxbase Test-2 -version -D__private_extern__=extern -o Test-2.s GNU C++ version 3.3 20030304 (Apple Computer, Inc. build 1435) (ppc-darwin) compiled by GNU C version 3.3 20030304 (Apple Computer, Inc. build 1435). GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=131072 Test-2.cpp: In constructor `A<T>::A(const A<U>&) [with U = int, T = float]': Test-2.cpp:26: instantiated from here Test-2.cpp:7: error: `int A<int>::_data' is protected Test-2.cpp:10: error: within this context The intermediate file: # 1 "Test-2.cpp" #pragma GCC set_debug_pwd "/Users/ktulu/Projects/Ktk/MacOs 10/Pb/Test" # 1 "<built-in>" # 1 "<command line>" # 1 "Test-2.cpp" template <typename T> class A { friend class A<int>; friend class A<float>; protected: T _data; inline A() : _data(0) {} template <typename U> inline A(const A<U>& r) : _data(r._data) {} }; class B : public A<int> { public: inline B() {} inline B(const B& r) : A<int>(r) {} }; class C : public A<float> { public: inline C() {} inline C(const B& r) : A<float>(r) {} }; int main(int, char*[]) { B b1, b2(b1); C c(b1); return 0; } The original code snippet: template <typename T> class A { friend class A<int>; friend class A<float>; protected: T _data; inline A() : _data(0) {} template <typename U> inline A(const A<U>& r) : _data(r._data) {} }; class B : public A<int> { public: inline B() {} inline B(const B& r) : A<int>(r) {} }; class C : public A<float> { public: inline C() {} inline C(const B& r) : A<float>(r) {} }; int main(int, char*[]) { B b1, b2(b1); C c(b1); return 0; }
I get the same error on 3.3.1 (20030707), 3.2.3, 3.0.4, and 2.95.3. Both with the mainline, I get: pr11876.cc: In instantiation of `A<int>': pr11876.cc:17: instantiated from here pr11876.cc:4: error: class `A<int>' is implicitly friends with itself pr11876.cc: In instantiation of `A<float>': pr11876.cc:24: instantiated from here pr11876.cc:4: error: class `A<float>' is implicitly friends with itself And with 2.91.66 I get the same as the mainline expect they are warnings instead of errors, I do not know what is the right thing though.
Confirmed as a bug. The problem is similar to PR641.
Patch submitted: http://gcc.gnu.org/ml/gcc-patches/2003-08/msg01344.html
Fixed by: * friend.c (add_friend): Add complain parameter. (make_friend_class): Likewise. (do_friend): Adjust add_friend call. * decl.c (grokdeclarator): Adjust make_friend_class call. * parser.c (cp_parser_member_declaration): Likewise. (cp_parser_template_declaration_after_exp): Likewise. * pt.c (instantiate_class_template): Adjust make_friend_class and add_friend call. * cp-tree.h (make_friend_class): Adjust declaration. (add_friend): Likewise. * g++.dg/template/friend22.C: New test. * g++.dg/template/friend23.C: Likewise.