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]

[gomp] Fix some CFG verification


When emitting error messages in the verifier about invalid labels, we would 
sometimes ICE if the label happened to be NULL.  This patch steps around 
the NULL label.

The patch adds a new debugging helper, debug_function, which just calls 
dump_function_to_file.  Inside dump_function_to_file, we now correctly 
switch to the function's CFUN to emit the local variables.

There is a third fix in the patch, which I think I will have to undo.  I 
used to get an ICE inside set_bb_for_stmt, because for some reason we were 
calling it during RTL expansion.  Since the label-to-block map doesn't 
exist at that point, we'd ICE.  So, the patch just ignores the 
label-to-block mapping during RTL expansion.

Unfortunately, I cannot reproduce this ICE anymore, so I'm thinking that 
this may have been a side-effect of another bug I was having in my code.  
Since I cannot reproduce this, I will undo this part (serves me right for 
trying to reproduce the problem after committing the patch).

Tested on x86.
2006-01-11  Diego Novillo  <dnovillo@redhat.com>

	* tree-dump.h (debug_function): Declare.
	* tree-cfg.c (set_bb_for_stmt): Do not update the
	block-to-labels map if we are currently expanding to RTL.
	(tree_node_can_be_shared): Remove unnecessary CONSTANT_CLASS_P
	checks.
	Handle IDENTIFIER_NODE.
	(tree_verify_flow_info): Do not ICE when emitting error
	messages about invalid labels.
	(dump_function_to_file): Reset CFUN before emitting the body
	of the function.
	(debug_function): New.


Index: tree-dump.h
===================================================================
--- tree-dump.h	(revision 109596)
+++ tree-dump.h	(working copy)
@@ -91,6 +91,7 @@ extern void queue_and_dump_index (dump_i
 extern void queue_and_dump_type (dump_info_p, tree);
 extern void dump_function (enum tree_dump_index, tree);
 extern void dump_function_to_file (tree, FILE *, int);
+extern void debug_function (tree, int);
 extern int dump_flag (dump_info_p, int, tree);
 
 extern unsigned int dump_register (const char *, const char *, const char *, 
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 109596)
+++ tree-cfg.c	(working copy)
@@ -2707,9 +2707,12 @@ set_bb_for_stmt (tree t, basic_block bb)
       stmt_ann_t ann = get_stmt_ann (t);
       ann->bb = bb;
 
-      /* If the statement is a label, add the label to block-to-labels map
-	 so that we can speed up edge creation for GOTO_EXPRs.  */
-      if (TREE_CODE (t) == LABEL_EXPR)
+      /* If the statement is a label, add the label to block-to-labels
+	 map so that we can speed up edge creation for GOTO_EXPRs.
+	 Note that LABEL_TO_BLOCK_MAP may not exist if we are
+	 currently expanding into RTL (in which case, this mapping is
+	 unnecessary, anyway).  */
+      if (TREE_CODE (t) == LABEL_EXPR && !currently_expanding_to_rtl)
 	{
 	  int uid;
 
@@ -3426,25 +3429,20 @@ static bool
 tree_node_can_be_shared (tree t)
 {
   if (IS_TYPE_OR_DECL_P (t)
-      /* We check for constants explicitly since they are not considered
-	 gimple invariants if they overflowed.  */
-      || CONSTANT_CLASS_P (t)
       || is_gimple_min_invariant (t)
       || TREE_CODE (t) == SSA_NAME
-      || t == error_mark_node)
+      || t == error_mark_node
+      || TREE_CODE (t) == IDENTIFIER_NODE)
     return true;
 
   if (TREE_CODE (t) == CASE_LABEL_EXPR)
     return true;
 
   while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
-	  /* We check for constants explicitly since they are not considered
-	     gimple invariants if they overflowed.  */
-	  && (CONSTANT_CLASS_P (TREE_OPERAND (t, 1))
-	      || is_gimple_min_invariant (TREE_OPERAND (t, 1))))
-	 || (TREE_CODE (t) == COMPONENT_REF
-	     || TREE_CODE (t) == REALPART_EXPR
-	     || TREE_CODE (t) == IMAGPART_EXPR))
+	   && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+	 || TREE_CODE (t) == COMPONENT_REF
+	 || TREE_CODE (t) == REALPART_EXPR
+	 || TREE_CODE (t) == IMAGPART_EXPR)
     t = TREE_OPERAND (t, 0);
 
   if (DECL_P (t))
@@ -3621,27 +3619,29 @@ tree_verify_flow_info (void)
 
 	  if (prev_stmt && DECL_NONLOCAL (LABEL_EXPR_LABEL (stmt)))
 	    {
-	      error ("nonlocal label %s is not first "
-		     "in a sequence of labels in bb %d",
-		     IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
-		     bb->index);
+	      error ("nonlocal label ");
+	      print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+	      fprintf (stderr, " is not first in a sequence of labels in bb %d",
+		       bb->index);
 	      err = 1;
 	    }
 
 	  if (label_to_block (LABEL_EXPR_LABEL (stmt)) != bb)
 	    {
-	      error ("label %s to block does not match in bb %d",
-		     IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
-		     bb->index);
+	      error ("label ");
+	      print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+	      fprintf (stderr, " to block does not match in bb %d",
+		       bb->index);
 	      err = 1;
 	    }
 
 	  if (decl_function_context (LABEL_EXPR_LABEL (stmt))
 	      != current_function_decl)
 	    {
-	      error ("label %s has incorrect context in bb %d",
-		     IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
-		     bb->index);
+	      error ("label ");
+	      print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+	      fprintf (stderr, " has incorrect context in bb %d",
+		       bb->index);
 	      err = 1;
 	    }
 	}
@@ -3663,12 +3663,13 @@ tree_verify_flow_info (void)
 
 	  if (TREE_CODE (stmt) == LABEL_EXPR)
 	    {
-	      error ("label %s in the middle of basic block %d",
-		     IDENTIFIER_POINTER (DECL_NAME (LABEL_EXPR_LABEL (stmt))),
-		     bb->index);
+	      error ("label ");
+	      print_generic_expr (stderr, LABEL_EXPR_LABEL (stmt), 0);
+	      fprintf (stderr, " in the middle of basic block %d", bb->index);
 	      err = 1;
 	    }
 	}
+
       bsi = bsi_last (bb);
       if (bsi_end_p (bsi))
 	continue;
@@ -3805,7 +3806,7 @@ tree_verify_flow_info (void)
 		  }
 		if (! tree_int_cst_lt (CASE_LOW (prev), CASE_LOW (c)))
 		  {
-		    error ("case labels not sorted:");
+		    error ("case labels not sorted: ");
 		    print_generic_expr (stderr, prev, 0);
 		    fprintf (stderr," is greater than ");
 		    print_generic_expr (stderr, c, 0);
@@ -4454,7 +4455,8 @@ dump_function_to_file (tree fn, FILE *fi
   bool ignore_topmost_bind = false, any_var = false;
   basic_block bb;
   tree chain;
-
+  struct function *saved_cfun;
+  
   fprintf (file, "%s (", lang_hooks.decl_printable_name (fn, 2));
 
   arg = DECL_ARGUMENTS (fn);
@@ -4475,6 +4477,10 @@ dump_function_to_file (tree fn, FILE *fi
       return;
     }
 
+  /* Switch CFUN to point to FN.  */
+  saved_cfun = cfun;
+  cfun = DECL_STRUCT_FUNCTION (fn);
+
   /* When GIMPLE is lowered, the variables are no longer available in
      BIND_EXPRs, so display them separately.  */
   if (cfun && cfun->decl == fn && cfun->unexpanded_var_list)
@@ -4516,7 +4522,7 @@ dump_function_to_file (tree fn, FILE *fi
       /* Make a tree based dump.  */
       chain = DECL_SAVED_TREE (fn);
 
-      if (TREE_CODE (chain) == BIND_EXPR)
+      if (chain && TREE_CODE (chain) == BIND_EXPR)
 	{
 	  if (ignore_topmost_bind)
 	    {
@@ -4542,6 +4548,18 @@ dump_function_to_file (tree fn, FILE *fi
     }
 
   fprintf (file, "\n\n");
+
+  /* Restore CFUN.  */
+  cfun = saved_cfun;
+}
+
+
+/* Dump FUNCTION_DECL FN to stderr using FLAGS (see TDF_* in tree.h)  */
+
+void
+debug_function (tree fn, int flags)
+{
+  dump_function_to_file (fn, stderr, flags);
 }
 
 

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