* pt.c (for_each_template_parm): Free allocated memory.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Nov 2002 05:17:01 +0000 (05:17 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Nov 2002 05:17:01 +0000 (05:17 +0000)
* search.c (is_subobject_of_p_1): New function.
(is_subobject_of_p): Avoid walking virtual bases multiple times.

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

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/search.c

index e3c47ab..d370dbd 100644 (file)
@@ -1,3 +1,9 @@
+2002-11-19  Mark Mitchell  <mark@codesourcery.com>
+
+       * pt.c (for_each_template_parm): Free allocated memory.
+       * search.c (is_subobject_of_p_1): New function.
+       (is_subobject_of_p): Avoid walking virtual bases multiple times.
+
 2002-11-19  Jason Thorpe  <thorpej@wasabisystems.com>
 
        * g++spec.c (lang_specific_spec_functions): New.
index db8e33f..67252f9 100644 (file)
@@ -4534,6 +4534,7 @@ for_each_template_parm (t, fn, data, visited)
      htab_t visited;
 {
   struct pair_fn_data pfd;
+  int result;
 
   /* Set up.  */
   pfd.fn = fn;
@@ -4549,10 +4550,16 @@ for_each_template_parm (t, fn, data, visited)
   else
     pfd.visited = htab_create (37, htab_hash_pointer, htab_eq_pointer, 
                               NULL);
-  return walk_tree (&t, 
-                   for_each_template_parm_r, 
-                   &pfd,
-                   NULL) != NULL_TREE;
+  result = walk_tree (&t, 
+                     for_each_template_parm_r, 
+                     &pfd,
+                     NULL) != NULL_TREE;
+
+  /* Clean up.  */
+  if (!visited)
+    htab_delete (pfd.visited);
+
+  return result;
 }
 
 int
index a4025ac..4170c16 100644 (file)
@@ -82,6 +82,7 @@ struct vbase_info
 
 static tree lookup_field_1 PARAMS ((tree, tree));
 static int is_subobject_of_p PARAMS ((tree, tree, tree));
+static int is_subobject_of_p_1 PARAMS ((tree, tree, tree));
 static tree dfs_check_overlap PARAMS ((tree, void *));
 static tree dfs_no_overlap_yet PARAMS ((tree, void *));
 static base_kind lookup_base_r
@@ -1099,13 +1100,11 @@ accessible_p (type, decl)
   return t != NULL_TREE;
 }
 
-/* Routine to see if the sub-object denoted by the binfo PARENT can be
-   found as a base class and sub-object of the object denoted by
-   BINFO.  MOST_DERIVED is the most derived type of the hierarchy being
-   searched.  */
+/* Recursive helper funciton for is_subobject_of_p; see that routine
+   for documentation of the parameters.  */
 
 static int
-is_subobject_of_p (parent, binfo, most_derived)
+is_subobject_of_p_1 (parent, binfo, most_derived)
      tree parent, binfo, most_derived;
 {
   tree binfos;
@@ -1121,19 +1120,50 @@ is_subobject_of_p (parent, binfo, most_derived)
   for (i = 0; i < n_baselinks; i++)
     {
       tree base_binfo = TREE_VEC_ELT (binfos, i);
-      if (!CLASS_TYPE_P (TREE_TYPE (base_binfo)))
+      tree base_type;
+
+      base_type = TREE_TYPE (base_binfo);
+      if (!CLASS_TYPE_P (base_type))
        /* If we see a TEMPLATE_TYPE_PARM, or some such, as a base
           class there's no way to descend into it.  */
        continue;
 
-      if (is_subobject_of_p (parent, 
-                             CANONICAL_BINFO (base_binfo, most_derived),
-                             most_derived))
+      /* Avoid walking into the same virtual base more than once.  */
+      if (TREE_VIA_VIRTUAL (base_binfo))
+       {
+         if (CLASSTYPE_MARKED4 (base_type))
+           return 0;
+         SET_CLASSTYPE_MARKED4 (base_type);
+         base_binfo = binfo_for_vbase (base_type, most_derived);
+       }
+
+      if (is_subobject_of_p_1 (parent, base_binfo, most_derived))
        return 1;
     }
   return 0;
 }
 
+/* Routine to see if the sub-object denoted by the binfo PARENT can be
+   found as a base class and sub-object of the object denoted by
+   BINFO.  MOST_DERIVED is the most derived type of the hierarchy being
+   searched.  */
+
+static int
+is_subobject_of_p (tree parent, tree binfo, tree most_derived)
+{
+  int result;
+  tree vbase;
+
+  result = is_subobject_of_p_1 (parent, binfo, most_derived);
+  /* Clear the mark bits on virtual bases.  */
+  for (vbase = CLASSTYPE_VBASECLASSES (most_derived);
+       vbase;
+       vbase = TREE_CHAIN (vbase))
+    CLEAR_CLASSTYPE_MARKED4 (TREE_TYPE (TREE_VALUE (vbase)));
+
+  return result;
+}
+
 struct lookup_field_info {
   /* The type in which we're looking.  */
   tree type;