bugfix: free_entity removed entity that still was in tarval hash table for tarval_p_...
authorGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Tue, 11 Mar 2003 16:12:10 +0000 (16:12 +0000)
committerGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Tue, 11 Mar 2003 16:12:10 +0000 (16:12 +0000)
[r870]

ir/tr/entity.c
ir/tv/tv.c
ir/tv/tv.h

index 24cee47..f38847d 100644 (file)
@@ -176,8 +176,10 @@ copy_entity_name (entity *old, ident *new_name) {
   return new;
 }
 
+
 void
 free_entity (entity *ent) {
+  free_tv_entity(ent);
   free_entity_attrs(ent);
   free(ent);
 }
index 1909b4f..657efe4 100644 (file)
@@ -1432,3 +1432,32 @@ entity *get_tv_entity(tarval *tv) {
   }
   return ent;
 }
+
+
+void
+free_tv_entity(entity *ent) {
+  /* There can be a tarval referencing this entity.
+     Even if the tarval is not used by the code any more,
+     it can still reference an entity.  If a hash function
+     happens to collide with this tarval, we will verify that
+     it contains a proper entity and we will crash.
+     As we cannot remove tarvals (they are on an obstack) we
+     overwrite ent with NULL. */
+  /* Get the tarval by allocating a new one. */
+  tarval *tv = (tarval *)pset_first(tarvals);
+  tarval *found = NULL;
+  while (tv) {
+    entity *tv_ent = get_tv_entity(tv);
+    if ((tv_ent) && (tv_ent == ent)) {
+      found = tv;
+      //pset_remove(tarvals, tv, tarval_hash(tv));
+      //tv->u.P.ent = NULL;
+      //  tv = NULL;
+    } //else {
+      tv = pset_next(tarvals);
+      //}
+  }
+  // pset_break(tarvals);
+  if (found)
+    pset_remove(tarvals, found, tarval_hash(found));
+}
index 6cd222d..39decd5 100644 (file)
@@ -206,6 +206,8 @@ ir_mode *get_tv_mode (tarval *tv);
 /** Returns the entity if the tv is a pointer to an entity, else
    returns NULL; */
 entity *get_tv_entity(tarval *tv);
+/* Removes tarvals that are pointers to ent. */
+void free_tv_entity(entity *ent);
 
 /** Returns 0 if tv is positive, else > 0. @todo not tested! */
 int tv_is_negative(tarval *a);