This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH]: fix bug 262 ICE
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH]: fix bug 262 ICE
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Mon, 26 Jun 2000 12:08:56 +0100
- Organization: Codesourcery LLC
Hi,
I've installed the attached patch and tests which fix bug 262
That report turned out to be user error, but we ICE before
telling so.
handle_class_head pushes the scope within which the decl it locates
resides. later on we pop the scope of the type to which that decl
refers to. If that decl is a typedef within one scope to a type in
another scope, we go bang! The common error is to write something like
class X::X
here X::X is the implicit typedef of ::X within its own scope. So we
push ::X as a scope, but pop ::.
Approved by Mark, built & tested on i686-pc-linux-gnu
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2000-06-23 Nathan Sidwell <nathan@codesourcery.com>
* decl2.c (handle_class_head): Bash typedefs to the type's main
decl.
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.370
diff -c -3 -p -r1.370 decl2.c
*** decl2.c 2000/06/23 01:14:39 1.370
--- decl2.c 2000/06/23 10:27:08
*************** handle_class_head (aggr, scope, id)
*** 5362,5368 ****
tree decl;
if (TREE_CODE (id) == TYPE_DECL)
! decl = id;
else if (DECL_CLASS_TEMPLATE_P (id))
decl = DECL_TEMPLATE_RESULT (id);
else
--- 5362,5370 ----
tree decl;
if (TREE_CODE (id) == TYPE_DECL)
! /* We must bash typedefs back to the main decl of the type. Otherwise
! we become confused about scopes. */
! decl = TYPE_MAIN_DECL (TREE_TYPE (id));
else if (DECL_CLASS_TEMPLATE_P (id))
decl = DECL_TEMPLATE_RESULT (id);
else
2000-06-26 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.pt/syntax1.C: New test.
* g++.old-deja/g++.pt/syntax2.C: New test.
* g++.old-deja/g++.other/syntax3.C: New test.
* g++.old-deja/g++.other/syntax4.C: New test.
Index: testsuite/g++.old-deja/g++.other/syntax3.C
===================================================================
RCS file: syntax3.C
diff -N syntax3.C
*** /dev/null Tue May 5 13:32:27 1998
--- syntax3.C Mon Jun 26 03:58:47 2000
***************
*** 0 ****
--- 1,21 ----
+ // Build don't link:
+
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 22 June 2000 <nathan@codesourcery.com>
+
+ // Origin GNATS bug report 262 from Jeremy Sanders <jss@ast.cam.ac.uk>
+ // and several others. With templates, it's very easy to say something
+ // erroneous like
+ // template class X::X<whatever>
+ // The culprit
+ // ... class X::X ...
+ // caused us to ICE as we got confused about pushing and popping scopes.
+
+ class X
+ {
+ public:
+ X();
+ };
+
+ class X::X () {} // ERROR - parse error
+ X::X () {}
Index: testsuite/g++.old-deja/g++.other/syntax4.C
===================================================================
RCS file: syntax4.C
diff -N syntax4.C
*** /dev/null Tue May 5 13:32:27 1998
--- syntax4.C Mon Jun 26 03:58:47 2000
***************
*** 0 ****
--- 1,26 ----
+ // Build don't link:
+
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 22 June 2000 <nathan@codesourcery.com>
+
+ // Origin GNATS bug report 262 from Jeremy Sanders <jss@ast.cam.ac.uk>
+ // and several others. With templates, it's very easy to say something
+ // erroneous like
+ // template class X::X<whatever>
+ // The culprit
+ // ... class X::X ...
+ // caused us to ICE as we got confused about pushing and popping scopes.
+
+ class X {
+ X ();
+ };
+
+ class Y {
+ public:
+ typedef ::X W;
+ class Z;
+ };
+
+ class Y::Z {};
+ class Y::W () {} // ERROR - parse error
+ Y::W::X () {}
Index: testsuite/g++.old-deja/g++.pt/syntax1.C
===================================================================
RCS file: syntax1.C
diff -N syntax1.C
*** /dev/null Tue May 5 13:32:27 1998
--- syntax1.C Mon Jun 26 03:58:47 2000
***************
*** 0 ****
--- 1,26 ----
+ // Build don't link:
+
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 22 June 2000 <nathan@codesourcery.com>
+
+ // Origin GNATS bug report 262 from Jeremy Sanders <jss@ast.cam.ac.uk>
+ // and several others. With templates, it's very easy to say something
+ // erroneous like
+ // template class X::X<whatever>
+ // The culprit
+ // ... class X::X ...
+ // caused us to ICE as we got confused about pushing and popping scopes.
+
+
+
+ class Y
+ {
+ public:
+ template <class T> Y(T &);
+ };
+ template <class T> Y::Y(T &) {}
+
+ template class Y::Y (int); // ERROR - parse error
+ template Y::Y (int); // ERROR - template-id does not match
+ template Y::Y (int &);
+
Index: testsuite/g++.old-deja/g++.pt/syntax2.C
===================================================================
RCS file: syntax2.C
diff -N syntax2.C
*** /dev/null Tue May 5 13:32:27 1998
--- syntax2.C Mon Jun 26 03:58:47 2000
***************
*** 0 ****
--- 1,27 ----
+ // Build don't link:
+
+ // Copyright (C) 2000 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 22 June 2000 <nathan@codesourcery.com>
+
+ // Origin GNATS bug report 262 from Jeremy Sanders <jss@ast.cam.ac.uk>
+ // and several others. With templates, it's very easy to say something
+ // erroneous like
+ // template class X::X<whatever>
+ // The culprit
+ // ... class X::X ...
+ // caused us to ICE as we got confused about pushing and popping scopes.
+
+ template <class T> class image
+ {
+ public:
+ template <class U> image(const image<U> ©);
+ };
+
+ template <class T> template <class U> image<T>::image(const image<U> ©)
+ {
+ }
+
+ template class image<double>;
+ template class image<double>::image (const image<int> &); // ERROR - parse error
+ template class image<double>::image (image<int>); // ERROR - specified as declarator-id
+ template image<double>::image (const image<int> &);