diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2000-11-23 15:19:36 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2000-11-23 15:19:36 +0000 |
commit | ab09753510d568c1bbca882b0e9b599e1c36e599 (patch) | |
tree | bc7f90c4051308ea11815a052b69c8fae03eea0f /gcc | |
parent | 8d4af2d7a964c875fd51a271eec2ede50c88068d (diff) | |
download | gcc-ab09753510d568c1bbca882b0e9b599e1c36e599.zip gcc-ab09753510d568c1bbca882b0e9b599e1c36e599.tar.gz gcc-ab09753510d568c1bbca882b0e9b599e1c36e599.tar.bz2 |
pt.c (lookup_template_class): Simplify loop exit constructs.
cp:
* pt.c (lookup_template_class): Simplify loop exit constructs.
Cope when there is no partial instantiation of a template
template member.
testsuite:
* g++.old-deja/g++.pt/instantiate9.C: New test.
From-SVN: r37698
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/pt.c | 49 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.pt/instantiate9.C | 25 |
4 files changed, 61 insertions, 23 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4e24762..ec50f9e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +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. + Thu Nov 23 02:16:47 2000 J"orn Rennecke <amylaar@redhat.com> * Make-lang.in (g++spec.o, cxxmain.o): Depend on $(CONFIG_H). diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index ddcdf8a..bbc6700 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3700,9 +3700,7 @@ maybe_get_template_decl_from_type_decl (decl) 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. + otherwise.) IN_DECL, if non-NULL, is the template declaration we are trying to instantiate. @@ -3925,23 +3923,16 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) 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; + 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 inolve template parameters. Note that we set + arguments still involve template parameters. Note that we set IS_PARTIAL_INSTANTIATION for partial specializations as well. */ is_partial_instantiation = uses_template_parms (arglist); @@ -4016,9 +4007,8 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) found = template; else { - /* This is a full instantiation of a member template. There - should be some partial instantiation of which this is an - instance. */ + /* 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)) @@ -4054,11 +4044,24 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) } if (!found) - my_friendly_abort (0); + { + /* 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)); + SET_TYPE_TEMPLATE_INFO (t, tree_cons (found, arglist, NULL_TREE)); DECL_TEMPLATE_INSTANTIATIONS (template) = tree_cons (arglist, t, DECL_TEMPLATE_INSTANTIATIONS (template)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b29f067..b3220ff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2000-11-23 Nathan Sidwell <nathan@codesourcery.com> + + * g++.old-deja/g++.pt/instantiate9.C: New test. + 2000-11-22 Mark Mitchell <mark@codesourcery.com> * g++.old-deja/g++.other/decl4.C: Tweak so that it fails with the diff --git a/gcc/testsuite/g++.old-deja/g++.pt/instantiate9.C b/gcc/testsuite/g++.old-deja/g++.pt/instantiate9.C new file mode 100644 index 0000000..30ad03b --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/instantiate9.C @@ -0,0 +1,25 @@ +// 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; +} |