The following code ICEs: // Line 1 class A { public: A() { }; ~A() { }; }; class B { public: B(); B(const A& a) { }; ~B(); }; template <typename X> class T; template <typename X, typename Y> T<X>* func(T<Y>* p); template <typename X> class T { X* m_; public: T(X* x) : m_(x) { }; ~T() { }; friend T<class Y>* func<Y, X>(T<X>* p); }; template <typename X, typename Y> T<X>* func(T<Y>* p) { return (new T<X>(new X(*p->m_))); } int main() { A* a = new A(); T<A>* p = new T<A>(a); T<B>* q = func<B, A>(p); return 0; }
Confirmed. Reduced testcase: ================================================ template<typename> struct A; template<typename T> void foo(A<T>* p) { *p; } template<typename> struct A { friend void foo<class X>(A<X>*); }; void bar() { foo<int>(0); } ================================================ Crashes mainline since at least 2005-05-25.
Is this really valid? class Y is undeclared at the point of the friend declaration... W.
The ICE: t.cc: In instantiation of ‘A<int>’: t.cc:4: instantiated from ‘void foo(A<T>*) [with T = int]’ t.cc:13: instantiated from here t.cc:8: internal compiler error: tree check: expected tree that contains ‘decl non-common’ structure, have ‘overload’ in get_bindings, at cp/pt.c:10657 Please submit a full bug report, with preprocessed source if appropriate. See <URL:http://gcc.gnu.org/bugs.html> for instructions.
A regression hunt on powerpc-linux shows the reduced testcase from comment #4 starts failing with this patch from lerdsuwa@gcc.gnu.org: http://gcc.gnu.org/ml/gcc-cvs/2005-03/msg00681.html
(In reply to comment #4) > A regression hunt on powerpc-linux shows the reduced testcase from comment #4 How wonderful, a recursive reference -- Janis's comment shows up as comment #4 :-)
I have two patches, one that produces (for the testcase in comment #1) /suse/rguenther/src/tests/pr22147-2.C: In instantiation of ‘A<int>’: /suse/rguenther/src/tests/pr22147-2.C:3: instantiated from ‘void foo(A<T>*) [with T = int]’ /suse/rguenther/src/tests/pr22147-2.C:12: instantiated from here /suse/rguenther/src/tests/pr22147-2.C:7: error: template-id ‘foo<X>’ for ‘void foo(A<X>*)’ does not match any template declaration and another one that doesn't complain and accepts the code as valid. So - is this valid code?
At least EDG accepts it in -strict_ansi mode.
If this is valid I won't be able to fix this really. Because just adding a forward declaration of class X fixes the problem the "simple fix" Index: cp/pt.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v retrieving revision 1.1029 diff -c -3 -p -r1.1029 pt.c *** cp/pt.c 5 Sep 2005 16:12:13 -0000 1.1029 --- cp/pt.c 9 Sep 2005 08:22:06 -0000 *************** get_bindings (tree fn, tree decl, tree e *** 10652,10657 **** --- 10652,10660 ---- /* We can get here for some invalid specializations. */ return NULL_TREE; + if (TREE_CODE (tmpl) == OVERLOAD) + tmpl = OVL_FUNCTION (tmpl); + converted_args = (coerce_template_parms (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), explicit_args, NULL_TREE, is for sure not the right one ;) Backtrace fyi #1 0x08443a42 in tree_contains_struct_check_failed (node=0x8620bc2, en=140643266, file=0x85827f4 "../../../src/gcc-unpatched/gcc/cp/pt.c", line=10656, function=0x858596d "get_bindings") at tree.c:5933 #2 0x080b654f in get_bindings (fn=0x40211b60, decl=0x40236000, explicit_args=0x40233888, check_rettype=1 '\001') at pt.c:10656 #3 0x0807d011 in determine_specialization (template_id=0x40194168, decl=0x40236000, targs_out=0xbfca1f50, need_member_template=0, template_count=1) at pt.c:1430 #4 0x08092640 in tsubst_friend_function (decl=0x40230e80, args=0x40233a38) at pt.c:5106 #5 0x080976ec in instantiate_class_template (type=0x40231c94) at pt.c:5859 #6 0x08102db0 in complete_type (type=0x40231c94) at typeck.c:118 #7 0x0811420b in convert_to_void (expr=0x4020f560, implicit=0x858e62d "statement") at cvt.c:863 #8 0x08129220 in finish_expr_stmt (expr=0x4020f560) at semantics.c:589 ... note that determine_specialization seems to deal with overloads already, so maybe should not call get_bindings here. whatever. NOT looking into this further.
Subject: Bug 22147 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2005-09-27 23:32:16 Modified files: gcc/cp : name-lookup.c pt.c ChangeLog gcc/testsuite/g++.dg/parse: crash28.C gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/template: friend37.C Log message: PR c++/22147 * name-lookup.c (maybe_process_template_type_declaration): Don't treat forward declarations of classes as templates just because we're processing_template_decl. * pt.c (tsubst_decl): Clear DECL_TEMPLATE_INFO for friend functions. PR c++/22147 * g++.dg/template/friend37.C: New test. * g++.dg/parse/crash28.C: Adjust error markers. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&r1=1.142&r2=1.143 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&r1=1.1038&r2=1.1039 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4903&r2=1.4904 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/crash28.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend37.C.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.6109&r2=1.6110
Fixed in 4.1.0.
This bug appeared on the 4.0 branch today. It was probably backported by your backport for PR 22603, Nathan. Could you please have a look?
bum!
Subject: Bug 22147 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: nathan@gcc.gnu.org 2005-10-18 16:39:07 Modified files: gcc/cp : ChangeLog pt.c name-lookup.c gcc/testsuite : ChangeLog gcc/testsuite/g++.dg/parse: crash28.C Added files: gcc/testsuite/g++.dg/template: friend37.C Log message: cp: PR c++/22147 Backport 2005-09-27 Mark Mitchell <mark@codesourcery.com> * name-lookup.c (maybe_process_template_type_declaration): Don't treat forward declarations of classes as templates just because we're processing_template_decl. * pt.c (tsubst_decl): Clear DECL_TEMPLATE_INFO for friend functions. testsuite: PR c++/22147 Backport 2005-09-27 Mark Mitchell <mark@codesourcery.com> * g++.dg/template/friend37.C: New test. * g++.dg/parse/crash28.C: Adjust error markers. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.4648.2.146&r2=1.4648.2.147 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/pt.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.978.2.35&r2=1.978.2.36 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.109.4.11&r2=1.109.4.12 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5084.2.470&r2=1.5084.2.471 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/friend37.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.14.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/parse/crash28.C.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1.2.1&r2=1.1.2.2
fixed on 4.0 branch 2005-10-18 Nathan Sidwell <nathan@codesourcery.com> PR c++/22147 Backport 2005-09-27 Mark Mitchell <mark@codesourcery.com> * name-lookup.c (maybe_process_template_type_declaration): Don't treat forward declarations of classes as templates just because we're processing_template_decl. * pt.c (tsubst_decl): Clear DECL_TEMPLATE_INFO for friend functions. PR c++/22147 Backport 2005-09-27 Mark Mitchell <mark@codesourcery.com> * g++.dg/template/friend37.C: New test. * g++.dg/parse/crash28.C: Adjust error markers.