diff options
author | Jason Merrill <jason@redhat.com> | 2008-01-22 09:48:05 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2008-01-22 09:48:05 -0500 |
commit | 29b0d1fd13249532adf239467d68bd4922e62d3c (patch) | |
tree | 17210cab7406b8b6b166eb18908a4cb69994b1fc /gcc | |
parent | 573fe0a122594bf28337f9d2d99c8005f1113940 (diff) | |
download | gcc-29b0d1fd13249532adf239467d68bd4922e62d3c.zip gcc-29b0d1fd13249532adf239467d68bd4922e62d3c.tar.gz gcc-29b0d1fd13249532adf239467d68bd4922e62d3c.tar.bz2 |
re PR c++/33959 (ICE in instantiate_class_template, at cp/pt.c:6649)
PR c++/33959
* pt.c (tsubst_aggr_type): Make sure our context is complete.
PR c++/34573
* pt.c (retrieve_local_specialization): Robustify.
(tsubst_pack_expansion, tsubst_decl): Remove redundant checks.
PR c++/34846
* pt.c (tsubst): Only call retrieve_local_specialization if the
original typedef was in a function template.
From-SVN: r131724
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/pt.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/nested5.C | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typedef10.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/typedef9.C | 25 |
5 files changed, 91 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fa48f7c..807f1b5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,16 @@ 2008-01-21 Jason Merrill <jason@redhat.com> + PR c++/33959 + * pt.c (tsubst_aggr_type): Make sure our context is complete. + + PR c++/34573 + * pt.c (retrieve_local_specialization): Robustify. + (tsubst_pack_expansion, tsubst_decl): Remove redundant checks. + + PR c++/34846 + * pt.c (tsubst): Only call retrieve_local_specialization if the + original typedef was in a function template. + PR c++/34196 * decl.c (wrap_cleanups_r): Set TRY_CATCH_IS_CLEANUP. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 87c4bf5..e61915d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -976,8 +976,13 @@ retrieve_specialization (tree tmpl, tree args, static tree retrieve_local_specialization (tree tmpl) { - tree spec = (tree) htab_find_with_hash (local_specializations, tmpl, - htab_hash_pointer (tmpl)); + tree spec; + + if (local_specializations == NULL) + return NULL_TREE; + + spec = (tree) htab_find_with_hash (local_specializations, tmpl, + htab_hash_pointer (tmpl)); return spec ? TREE_PURPOSE (spec) : NULL_TREE; } @@ -7305,10 +7310,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, tree orig_arg = NULL_TREE; if (TREE_CODE (parm_pack) == PARM_DECL) - { - if (local_specializations) - arg_pack = retrieve_local_specialization (parm_pack); - } + arg_pack = retrieve_local_specialization (parm_pack); else { int level, idx, levels; @@ -7688,8 +7690,14 @@ tsubst_aggr_type (tree t, up. */ context = TYPE_CONTEXT (t); if (context) - context = tsubst_aggr_type (context, args, complain, - in_decl, /*entering_scope=*/1); + { + context = tsubst_aggr_type (context, args, complain, + in_decl, /*entering_scope=*/1); + /* If context is a nested class inside a class template, + it may still need to be instantiated (c++/33959). */ + if (TYPE_P (context)) + context = complete_type (context); + } /* Then, figure out what arguments are appropriate for the type we are trying to find. For example, given: @@ -8201,9 +8209,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) substitution from inside tsubst_pack_expansion. Just return the local specialization (which will be a single parm). */ - tree spec = NULL_TREE; - if (local_specializations) - spec = retrieve_local_specialization (t); + tree spec = retrieve_local_specialization (t); if (spec && TREE_CODE (spec) == PARM_DECL && TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION) @@ -8855,11 +8861,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl); r = retrieve_specialization (tmpl, gen_args, false); } - else if (DECL_FUNCTION_SCOPE_P (decl)) + else if (DECL_FUNCTION_SCOPE_P (decl) + && DECL_TEMPLATE_INFO (DECL_CONTEXT (decl))) r = retrieve_local_specialization (decl); else - r = NULL_TREE; - + /* The typedef is from a non-template context. */ + return t; + if (r) { r = TREE_TYPE (r); diff --git a/gcc/testsuite/g++.dg/template/nested5.C b/gcc/testsuite/g++.dg/template/nested5.C new file mode 100644 index 0000000..3850fda --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nested5.C @@ -0,0 +1,19 @@ +// PR c++/33959 + +template <typename T> struct A +{ + struct C + { + template <typename U> struct D {}; + }; + template <typename S> static C::D<S> bar (S const &); +}; + +struct E {}; + +int +main () +{ + E e; + A<E>::bar (e); +} diff --git a/gcc/testsuite/g++.dg/template/typedef10.C b/gcc/testsuite/g++.dg/template/typedef10.C new file mode 100644 index 0000000..c2a2108 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef10.C @@ -0,0 +1,14 @@ +// PR c++/34573 + +template < class Gtr_> +void compute_gr() +{ + typedef int Less_chain; + struct utils { + utils(const Less_chain& lc) {}; + }; + utils U(1); +} +int main(void){ + compute_gr<int>(); +} diff --git a/gcc/testsuite/g++.dg/template/typedef9.C b/gcc/testsuite/g++.dg/template/typedef9.C new file mode 100644 index 0000000..8d2ed36 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/typedef9.C @@ -0,0 +1,25 @@ +// PR c++/34846 + +template<typename, typename> struct __are_same { enum { __value = 0 }; }; +template<typename _Tp> struct __are_same<_Tp, _Tp> { enum { __value = 1 }; }; +template<typename, bool> struct __enable_if { }; +template<typename _Tp> struct __enable_if<_Tp, true> { typedef _Tp __type; }; +template<typename _Iterator, typename _Container> class __normal_iterator { +public: + __normal_iterator(); + template<typename _Iter> + __normal_iterator( + const __normal_iterator<_Iter, typename __enable_if<_Container, +(__are_same<_Iter, typename _Container::pointer>::__value) >::__type>& __i) + { } +}; +template<typename _Tp> class vector { +public: + typedef _Tp* pointer; + typedef __normal_iterator<int, vector<_Tp> > iterator; +}; +void test() { + typedef int t; + vector<t*>::iterator x; + vector<t*>::iterator y = x; +} |