Bug 22147 - [4.0 regression] ICE in get_bindings
Summary: [4.0 regression] ICE in get_bindings
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.0.3
Assignee: Nathan Sidwell
URL:
Keywords: ice-on-valid-code, monitored
Depends on:
Blocks:
 
Reported: 2005-06-22 18:14 UTC by Andrew Pinski
Modified: 2005-10-18 16:41 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-10-15 14:44:50


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Pinski 2005-06-22 18:14:09 UTC
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;
}
Comment 1 Volker Reichelt 2005-06-22 21:41:41 UTC
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.
Comment 2 Wolfgang Bangerth 2005-06-23 02:45:22 UTC
Is this really valid? class Y is undeclared at the point of the friend declaration...

W.
Comment 3 Andrew Pinski 2005-08-02 23:51:03 UTC
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.
Comment 4 Janis Johnson 2005-09-08 23:43:30 UTC
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
Comment 5 Wolfgang Bangerth 2005-09-09 00:09:55 UTC
(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 :-) 
 
Comment 6 Richard Biener 2005-09-09 08:21:13 UTC
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?
Comment 7 Richard Biener 2005-09-09 09:25:25 UTC
At least EDG accepts it in -strict_ansi mode.
Comment 8 Richard Biener 2005-09-09 09:42:06 UTC
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.
Comment 9 GCC Commits 2005-09-27 23:33:19 UTC
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

Comment 10 Mark Mitchell 2005-09-27 23:33:50 UTC
Fixed in 4.1.0.
Comment 11 Volker Reichelt 2005-10-15 09:58:23 UTC
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?
Comment 12 Nathan Sidwell 2005-10-15 14:44:50 UTC
bum!
Comment 13 GCC Commits 2005-10-18 16:39:11 UTC
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

Comment 14 Nathan Sidwell 2005-10-18 16:41:07 UTC
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.