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>
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.
......
......@@ -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);
......
// 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