This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

EH dumping and verification improvements


Hi,
this patch makes dump_eh_tree to dump more stuff and verify_eh_tree to verify more invariants.
Bootstrapped/regtested x86_64-linux on pretty-ipa and comitting it there.  Will commit it
to mainline too unless there are complains or bootstrap/regtesting x86_64-linux fails.

Honza

	* except.c (dump_eh_tree): Output all fields.
	(verify_eh_region): New.
	(verify_eh_tree): Use it.
Index: except.c
===================================================================
--- except.c	(revision 145786)
+++ except.c	(working copy)
@@ -4274,6 +4525,28 @@
 	  fprintf (out, " tree_label:");
 	  print_generic_expr (out, i->tree_label, 0);
 	}
+      if (i->label)
+	fprintf (out, " label:%i", INSN_UID (i->label));
+      if (i->landing_pad)
+	{
+          fprintf (out, " landing_pad:%i", INSN_UID (i->landing_pad));
+	  if (GET_CODE (i->landing_pad) == NOTE)
+	    fprintf (out, " (deleted)");
+        }
+      if (i->post_landing_pad)
+	{
+          fprintf (out, " post_landing_pad:%i", INSN_UID (i->post_landing_pad));
+	  if (GET_CODE (i->post_landing_pad) == NOTE)
+	    fprintf (out, " (deleted)");
+	}
+      if (i->resume)
+	{
+          fprintf (out, " resume:%i", INSN_UID (i->resume));
+	  if (GET_CODE (i->resume) == NOTE)
+	    fprintf (out, " (deleted)");
+	}
+      if (i->may_contain_throw)
+        fprintf (out, " may_contain_throw");
       switch (i->type)
 	{
 	case ERT_CLEANUP:
@@ -4298,15 +4571,17 @@
 	  if (i->u.eh_catch.next_catch)
 	    fprintf (out, " next %i",
 		     i->u.eh_catch.next_catch->region_number);
+	  fprintf (out, " type:");
+	  print_generic_expr (out, i->u.eh_catch.type_list, 0);
 	  break;
 
 	case ERT_ALLOWED_EXCEPTIONS:
-	  fprintf (out, "filter :%i types:", i->u.allowed.filter);
+	  fprintf (out, " filter :%i types:", i->u.allowed.filter);
 	  print_generic_expr (out, i->u.allowed.type_list, 0);
 	  break;
 
 	case ERT_THROW:
-	  fprintf (out, "type:");
+	  fprintf (out, " type:");
 	  print_generic_expr (out, i->u.eh_throw.type, 0);
 	  break;
 
@@ -4345,8 +4620,86 @@
     }
 }
 
-/* Verify some basic invariants on EH datastructures.  Could be extended to
-   catch more.  */
+/* Verify EH region invariants.  */
+
+static bool
+verify_eh_region (struct eh_region *region, struct eh_region *prev_try)
+{
+  bool found = false;
+  if (!region)
+    return false;
+  switch (region->type)
+    {
+    case ERT_CLEANUP:
+      if (region->u.cleanup.prev_try != prev_try)
+	{
+	  error ("Wrong prev_try pointer in EH region %i",
+		 region->region_number);
+	  found = true;
+	}
+      break;
+    case ERT_TRY:
+      {
+	struct eh_region *c, *prev = NULL;
+	if (region->u.eh_try.eh_catch->u.eh_catch.prev_catch)
+	  {
+	    error ("Try region %i has wrong rh_catch pointer to %i",
+		   region->region_number,
+		   region->u.eh_try.eh_catch->region_number);
+	    found = true;
+	  }
+	for (c = region->u.eh_try.eh_catch; c; c = c->u.eh_catch.next_catch)
+	  {
+	    if (c->outer != region->outer)
+	      {
+		error
+		  ("Catch region %i has different outer region than try region %i",
+		   c->region_number, region->region_number);
+		found = true;
+	      }
+	    if (c->u.eh_catch.prev_catch != prev)
+	      {
+		error ("Catch region %i has corrupted catchlist",
+		       c->region_number);
+		found = true;
+	      }
+	    prev = c;
+	  }
+	if (prev != region->u.eh_try.last_catch)
+	  {
+	    error
+	      ("Try region %i has wrong last_catch pointer to %i instead of %i",
+	       region->region_number,
+	       region->u.eh_try.last_catch->region_number,
+	       prev->region_number);
+	    found = true;
+	  }
+      }
+      break;
+    case ERT_CATCH:
+      if (!region->u.eh_catch.next_catch
+          && (!region->next_peer || region->next_peer->type != ERT_TRY))
+	{
+	  error ("Catch region %i should be followed by try", region->region_number);
+	  found = true;
+	}
+      break;
+    case ERT_ALLOWED_EXCEPTIONS:
+    case ERT_MUST_NOT_THROW:
+    case ERT_THROW:
+      break;
+    case ERT_UNKNOWN:
+      gcc_unreachable ();
+    }
+  if (region->type == ERT_TRY)
+    prev_try = region;
+  for (region = region->inner; region; region = region->next_peer)
+    found |= verify_eh_region (region, prev_try);
+  return found;
+}
+
+/* Verify invariants on EH datastructures.  */
+
 void
 verify_eh_tree (struct function *fun)
 {
@@ -4423,6 +4776,10 @@
 		      error ("array does not match the region tree");
 		      err = true;
 		    }
+		  if (!err)
+		    for (i = fun->eh->region_tree; i; i = i->next_peer)
+		      err |= verify_eh_region (i, NULL);
+		  
 		  if (err)
 		    {
 		      dump_eh_tree (stderr, fun);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]