PR c++/33959
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jan 2008 14:48:05 +0000 (14:48 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Jan 2008 14:48:05 +0000 (14:48 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131724 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/template/nested5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/typedef10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/typedef9.C [new file with mode: 0644]

index fa48f7c..807f1b5 100644 (file)
@@ -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.
 
index 87c4bf5..e61915d 100644 (file)
@@ -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 (file)
index 0000000..3850fda
--- /dev/null
@@ -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 (file)
index 0000000..c2a2108
--- /dev/null
@@ -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 (file)
index 0000000..8d2ed36
--- /dev/null
@@ -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;
+}