]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/33964 (internal compiler error: in dependent_type_p, at cp/pt.c:15319 ...
authorDouglas Gregor <doug.gregor@gmail.com>
Tue, 15 Jan 2008 16:09:28 +0000 (16:09 +0000)
committerDoug Gregor <dgregor@gcc.gnu.org>
Tue, 15 Jan 2008 16:09:28 +0000 (16:09 +0000)
2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/33964
       * pt.c (process_partial_specialization): Don't mark template
       parameters that occur in non-deduced contexts.
       (struct pair_fn_data): Add include_nondeduced_p.
       (for_each_template_parm_r): Only visit non-deduced contexts if
       include_nondeduced_p is set.
       (for_each_template_parm): Added parameter include_nondeduced_p,
       which states whether template parameters found in non-deduced
       contexts should be visited.
       (uses_template_parms): Visit all template parameters, even those
       in non-deduced contexts.

2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>

       PR c++/33964
       * g++.dg/cpp0x/vt-33964.C: New.
       * g++.dg/template/partial5.C: New.

From-SVN: r131544

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/vt-33964.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/partial5.C [new file with mode: 0644]

index 4125ade97577ebf147a86d7ead3c1859dd7a64a9..e464d91b914fe008056dd3e0f985a7d5c7a17ed6 100644 (file)
@@ -1,3 +1,17 @@
+2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/33964
+       * pt.c (process_partial_specialization): Don't mark template
+       parameters that occur in non-deduced contexts.
+       (struct pair_fn_data): Add include_nondeduced_p.
+       (for_each_template_parm_r): Only visit non-deduced contexts if
+       include_nondeduced_p is set.
+       (for_each_template_parm): Added parameter include_nondeduced_p,
+       which states whether template parameters found in non-deduced
+       contexts should be visited.
+       (uses_template_parms): Visit all template parameters, even those
+       in non-deduced contexts.
+
 2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
 
        PR c++/34052
index b9c40b209b10a35bb5d22c01a9778864c5cf3517..409b123a480416999b23e097a5a1476ff446ea3c 100644 (file)
@@ -125,7 +125,7 @@ static tree convert_nontype_argument (tree, tree);
 static tree convert_template_argument (tree, tree, tree,
                                       tsubst_flags_t, int, tree);
 static int for_each_template_parm (tree, tree_fn_t, void*,
-                                  struct pointer_set_t*);
+                                  struct pointer_set_t*, bool);
 static tree expand_template_argument_pack (tree);
 static tree build_template_parm_index (int, int, int, tree, tree);
 static bool inline_needs_template_parms (tree);
@@ -3378,7 +3378,8 @@ process_partial_specialization (tree decl)
       for_each_template_parm (TREE_VEC_ELT (inner_args, i),
                              &mark_template_parm,
                              &tpd,
-                             NULL);
+                             NULL,
+                             /*include_nondeduced_p=*/false);
     }
   for (i = 0; i < ntparms; ++i)
     if (tpd.parms[i] == 0)
@@ -3501,7 +3502,8 @@ process_partial_specialization (tree decl)
                   for_each_template_parm (type,
                                           &mark_template_parm,
                                           &tpd2,
-                                          NULL);
+                                          NULL,
+                                         /*include_nondeduced_p=*/false);
 
                   if (tpd2.arg_uses_template_parms [i])
                     {
@@ -5929,6 +5931,9 @@ struct pair_fn_data
 {
   tree_fn_t fn;
   void *data;
+  /* True when we should also visit template parameters that occur in
+     non-deduced contexts.  */
+  bool include_nondeduced_p;
   struct pointer_set_t *visited;
 };
 
@@ -5943,7 +5948,9 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
   void *data = pfd->data;
 
   if (TYPE_P (t)
-      && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited))
+      && (pfd->include_nondeduced_p || TREE_CODE (t) != TYPENAME_TYPE)
+      && for_each_template_parm (TYPE_CONTEXT (t), fn, data, pfd->visited,
+                                pfd->include_nondeduced_p))
     return error_mark_node;
 
   switch (TREE_CODE (t))
@@ -5958,15 +5965,18 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       if (!TYPE_TEMPLATE_INFO (t))
        *walk_subtrees = 0;
       else if (for_each_template_parm (TREE_VALUE (TYPE_TEMPLATE_INFO (t)),
-                                      fn, data, pfd->visited))
+                                      fn, data, pfd->visited, 
+                                      pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case INTEGER_TYPE:
       if (for_each_template_parm (TYPE_MIN_VALUE (t),
-                                 fn, data, pfd->visited)
+                                 fn, data, pfd->visited, 
+                                 pfd->include_nondeduced_p)
          || for_each_template_parm (TYPE_MAX_VALUE (t),
-                                    fn, data, pfd->visited))
+                                    fn, data, pfd->visited,
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -5974,13 +5984,14 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       /* Since we're not going to walk subtrees, we have to do this
         explicitly here.  */
       if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data,
-                                 pfd->visited))
+                                 pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
     case FUNCTION_TYPE:
       /* Check the return type.  */
-      if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
+      if (for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+                                 pfd->include_nondeduced_p))
        return error_mark_node;
 
       /* Check the parameter types.  Since default arguments are not
@@ -5994,7 +6005,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
 
        for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm))
          if (for_each_template_parm (TREE_VALUE (parm), fn, data,
-                                     pfd->visited))
+                                     pfd->visited, pfd->include_nondeduced_p))
            return error_mark_node;
 
        /* Since we've already handled the TYPE_ARG_TYPES, we don't
@@ -6004,8 +6015,10 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
       break;
 
     case TYPEOF_TYPE:
-      if (for_each_template_parm (TYPE_FIELDS (t), fn, data,
-                                 pfd->visited))
+      if (pfd->include_nondeduced_p
+         && for_each_template_parm (TYPE_FIELDS (t), fn, data,
+                                    pfd->visited, 
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -6013,7 +6026,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case VAR_DECL:
       if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)
          && for_each_template_parm (DECL_TI_ARGS (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
@@ -6021,17 +6034,19 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case CONST_DECL:
       if (TREE_CODE (t) == CONST_DECL && DECL_TEMPLATE_PARM_P (t)
          && for_each_template_parm (DECL_INITIAL (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       if (DECL_CONTEXT (t)
+         && pfd->include_nondeduced_p
          && for_each_template_parm (DECL_CONTEXT (t), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case BOUND_TEMPLATE_TEMPLATE_PARM:
       /* Record template parameters such as `T' inside `TT<T>'.  */
-      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited))
+      if (for_each_template_parm (TYPE_TI_ARGS (t), fn, data, pfd->visited,
+                                 pfd->include_nondeduced_p))
        return error_mark_node;
       /* Fall through.  */
 
@@ -6047,7 +6062,8 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case TEMPLATE_DECL:
       /* A template template parameter is encountered.  */
       if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)
-         && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited))
+         && for_each_template_parm (TREE_TYPE (t), fn, data, pfd->visited,
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
 
       /* Already substituted template template parameter */
@@ -6057,15 +6073,17 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
     case TYPENAME_TYPE:
       if (!fn
          || for_each_template_parm (TYPENAME_TYPE_FULLNAME (t), fn,
-                                    data, pfd->visited))
+                                    data, pfd->visited, 
+                                    pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
     case CONSTRUCTOR:
       if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))
+         && pfd->include_nondeduced_p
          && for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE
                                     (TREE_TYPE (t)), fn, data,
-                                    pfd->visited))
+                                    pfd->visited, pfd->include_nondeduced_p))
        return error_mark_node;
       break;
 
@@ -6106,11 +6124,16 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
    for_each_template_parm returns 1.  Otherwise, the iteration
    continues.  If FN never returns a nonzero value, the value
    returned by for_each_template_parm is 0.  If FN is NULL, it is
-   considered to be the function which always returns 1.  */
+   considered to be the function which always returns 1.
+
+   If INCLUDE_NONDEDUCED_P, then this routine will also visit template
+   parameters that occur in non-deduced contexts.  When false, only
+   visits those template parameters that can be deduced.  */
 
 static int
 for_each_template_parm (tree t, tree_fn_t fn, void* data,
-                       struct pointer_set_t *visited)
+                       struct pointer_set_t *visited,
+                       bool include_nondeduced_p)
 {
   struct pair_fn_data pfd;
   int result;
@@ -6118,6 +6141,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
   /* Set up.  */
   pfd.fn = fn;
   pfd.data = data;
+  pfd.include_nondeduced_p = include_nondeduced_p;
 
   /* Walk the tree.  (Conceptually, we would like to walk without
      duplicates, but for_each_template_parm_r recursively calls
@@ -6189,7 +6213,8 @@ uses_template_parms (tree t)
 int
 uses_template_parms_level (tree t, int level)
 {
-  return for_each_template_parm (t, template_parm_this_level_p, &level, NULL);
+  return for_each_template_parm (t, template_parm_this_level_p, &level, NULL,
+                                /*include_nondeduced_p=*/true);
 }
 
 static int tinst_depth;
index 7aef4010b2828a990df6fbf00fa0b46b32778745..3ae1bd2ff1d4a806677f0251d0a202ac3cbb74cc 100644 (file)
@@ -1,3 +1,9 @@
+2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/33964
+       * g++.dg/cpp0x/vt-33964.C: New.
+       * g++.dg/template/partial5.C: New.
+
 2008-01-15  Douglas Gregor  <doug.gregor@gmail.com>
 
        PR c++/34052
diff --git a/gcc/testsuite/g++.dg/cpp0x/vt-33964.C b/gcc/testsuite/g++.dg/cpp0x/vt-33964.C
new file mode 100644 (file)
index 0000000..0b84b6c
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-options "-std=c++0x" }
+template<typename ... Args>
+struct foo
+{
+    static bool const value = true;
+};
+
+template<typename ... Args>
+struct foo< typename Args::is_applied... > // { dg-error "not used|Args" }
+{
+    static bool const value = false;
+};
+
+struct not_applied { typedef void is_applied; };
+struct applied { typedef applied is_applied; };
+
+int main()
+{
+    foo<applied, applied> i;
+}
diff --git a/gcc/testsuite/g++.dg/template/partial5.C b/gcc/testsuite/g++.dg/template/partial5.C
new file mode 100644 (file)
index 0000000..aa32e3b
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/33964
+
+template<typename T>
+struct X { };
+
+template<typename T>
+struct X<typename T::foo> { }; // { dg-error "not used|T" }
+
+template<int N>
+struct X<int[N]> {}; // okay
+
+
+template<typename T, typename T::foo V>
+struct Y { };
+
+template<typename T, typename U, U v>
+struct Y<T, v> { }; // { dg-error "not used|U" }
+
+
+template<typename T, T V>
+struct Z { };
+
+template<typename T>
+struct Z<T, (T)0> { }; // { dg-error "involves template parameter" }