This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ patch] Fix bug 789
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ patch] Fix bug 789
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Thu, 23 Nov 2000 15:24:23 +0000
- Organization: Codesourcery LLC
Hi,
I've installed this which fixes bug 789 where we ICE'd because we expected
to find a partial instantiation of a template template member when
nstantiating an instance of it. That assumption is false when it's
A<T>::C<int> as in this test case.
So the fix is to generate the partial instantiation, if we failed to
find it. Also tidied up some comments and confusing looping logic
in lookup_template_class.
built & tested on i686-pc-linux-gnu, approved by Mark
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-11-23 Nathan Sidwell <nathan@codesourcery.com>
* pt.c (lookup_template_class): Simplify loop exit constructs.
Cope when there is no partial instantiation of a template
template member.
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.478
diff -c -3 -p -r1.478 pt.c
*** pt.c 2000/11/17 12:36:26 1.478
--- pt.c 2000/11/23 08:43:12
*************** maybe_get_template_decl_from_type_decl (
*** 3700,3708 ****
D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
(Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will
be a TREE_LIST if called directly from the parser, and a TREE_VEC
! otherwise.) Since ARGLIST is build on the temp_decl_obstack, we must
! copy it here to keep it from being reclaimed when the decl storage
! is reclaimed.
IN_DECL, if non-NULL, is the template declaration we are trying to
instantiate.
--- 3700,3706 ----
D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments.
(Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will
be a TREE_LIST if called directly from the parser, and a TREE_VEC
! otherwise.)
IN_DECL, if non-NULL, is the template declaration we are trying to
instantiate.
*************** lookup_template_class (d1, arglist, in_d
*** 3925,3947 ****
found = NULL_TREE;
}
}
-
- if (!found)
- {
- for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
- found; found = TREE_CHAIN (found))
- if (comp_template_args (TREE_PURPOSE (found), arglist))
- break;
-
- if (found)
- found = TREE_VALUE (found);
- }
-
if (found)
! return found;
/* This type is a "partial instantiation" if any of the template
! arguments still inolve template parameters. Note that we set
IS_PARTIAL_INSTANTIATION for partial specializations as
well. */
is_partial_instantiation = uses_template_parms (arglist);
--- 3923,3938 ----
found = NULL_TREE;
}
}
if (found)
! return found;
!
! for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
! found; found = TREE_CHAIN (found))
! if (comp_template_args (TREE_PURPOSE (found), arglist))
! return TREE_VALUE (found);
/* This type is a "partial instantiation" if any of the template
! arguments still involve template parameters. Note that we set
IS_PARTIAL_INSTANTIATION for partial specializations as
well. */
is_partial_instantiation = uses_template_parms (arglist);
*************** lookup_template_class (d1, arglist, in_d
*** 4016,4024 ****
found = template;
else
{
! /* This is a full instantiation of a member template. There
! should be some partial instantiation of which this is an
! instance. */
for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
found; found = TREE_CHAIN (found))
--- 4007,4014 ----
found = template;
else
{
! /* This is a full instantiation of a member template. Look
! for a partial instantiation of which this is an instance. */
for (found = DECL_TEMPLATE_INSTANTIATIONS (template);
found; found = TREE_CHAIN (found))
*************** lookup_template_class (d1, arglist, in_d
*** 4054,4064 ****
}
if (!found)
! my_friendly_abort (0);
}
! SET_TYPE_TEMPLATE_INFO (t,
! tree_cons (found, arglist, NULL_TREE));
DECL_TEMPLATE_INSTANTIATIONS (template)
= tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (template));
--- 4044,4067 ----
}
if (!found)
! {
! /* There was no partial instantiation. This happens
! where C<T> is a member template of A<T> and it's used
! in something like
!
! template <typename T> struct B { A<T>::C<int> m; };
! B<float>;
!
! Create the partial instantiation.
! */
! TREE_VEC_LENGTH (arglist)--;
! template = tsubst (template, arglist, /*complain=*/0, NULL_TREE);
! TREE_VEC_LENGTH (arglist)++;
! found = template;
! }
}
! SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE));
DECL_TEMPLATE_INSTANTIATIONS (template)
= tree_cons (arglist, t,
DECL_TEMPLATE_INSTANTIATIONS (template));
// Build don't link:
// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 22 Nov 2000 <nathan@codesourcery.com>
// Bug 789. We ICE'd trying to instantiate B<float> because there was no
// existing partial specialization of C in A<float>.
template <typename T>
struct A {
template <typename D1>
struct C { };
};
template <typename T1>
struct B {
A<T1>::C<int> s1;
};
int main()
{
B<float> b;
return 0;
}