Commit 29b0d1fd by Jason Merrill Committed by Jason Merrill

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
parent 573fe0a1
2008-01-21 Jason Merrill <jason@redhat.com> 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 PR c++/34196
* decl.c (wrap_cleanups_r): Set TRY_CATCH_IS_CLEANUP. * decl.c (wrap_cleanups_r): Set TRY_CATCH_IS_CLEANUP.
......
...@@ -976,8 +976,13 @@ retrieve_specialization (tree tmpl, tree args, ...@@ -976,8 +976,13 @@ retrieve_specialization (tree tmpl, tree args,
static tree static tree
retrieve_local_specialization (tree tmpl) retrieve_local_specialization (tree tmpl)
{ {
tree spec = (tree) htab_find_with_hash (local_specializations, tmpl, tree spec;
htab_hash_pointer (tmpl));
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; return spec ? TREE_PURPOSE (spec) : NULL_TREE;
} }
...@@ -7305,10 +7310,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, ...@@ -7305,10 +7310,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
tree orig_arg = NULL_TREE; tree orig_arg = NULL_TREE;
if (TREE_CODE (parm_pack) == PARM_DECL) if (TREE_CODE (parm_pack) == PARM_DECL)
{ arg_pack = retrieve_local_specialization (parm_pack);
if (local_specializations)
arg_pack = retrieve_local_specialization (parm_pack);
}
else else
{ {
int level, idx, levels; int level, idx, levels;
...@@ -7688,8 +7690,14 @@ tsubst_aggr_type (tree t, ...@@ -7688,8 +7690,14 @@ tsubst_aggr_type (tree t,
up. */ up. */
context = TYPE_CONTEXT (t); context = TYPE_CONTEXT (t);
if (context) 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 /* Then, figure out what arguments are appropriate for the
type we are trying to find. For example, given: type we are trying to find. For example, given:
...@@ -8201,9 +8209,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) ...@@ -8201,9 +8209,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
substitution from inside tsubst_pack_expansion. Just substitution from inside tsubst_pack_expansion. Just
return the local specialization (which will be a single return the local specialization (which will be a single
parm). */ parm). */
tree spec = NULL_TREE; tree spec = retrieve_local_specialization (t);
if (local_specializations)
spec = retrieve_local_specialization (t);
if (spec if (spec
&& TREE_CODE (spec) == PARM_DECL && TREE_CODE (spec) == PARM_DECL
&& TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION) && TREE_CODE (TREE_TYPE (spec)) != TYPE_PACK_EXPANSION)
...@@ -8855,11 +8861,13 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -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); tree gen_args = tsubst (DECL_TI_ARGS (decl), args, complain, in_decl);
r = retrieve_specialization (tmpl, gen_args, false); 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); r = retrieve_local_specialization (decl);
else else
r = NULL_TREE; /* The typedef is from a non-template context. */
return t;
if (r) if (r)
{ {
r = TREE_TYPE (r); r = TREE_TYPE (r);
......
// 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);
}
// 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>();
}
// 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment