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]

[PATCH] Verify that context of local DECLs is the current function


Hi,

the patch below moves an assert from expand_expr_real_1 to gimple
verification.  It triggers when we do a sloppy job outlining stuff
from one function to another (or perhaps inlining too) and leave in
the IL of a function a local declaration that belongs to a different
function.

Like I wrote above, such cases usually ICE in expand anyway, but I
think it is worth bailing out sooner, if nothing because bugs like PR
70348 would not be assigned to me ;-) ...well, actually, I found this
helpful when working on OpenMP gridification.

In the process, I think that the verifier would not catch a
SSA_NAME_IN_FREE_LIST when such an SSA_NAME is a base of a MEM_REF so
I added that check too.

Bootstrapped and tested on x86_64-linux, OK for trunk?

Thanks,

Martin



2016-04-21  Martin Jambor  <mjambor@suse.cz>

	* tree-cfg.c (verify_var_parm_result_decl): New function.
	(verify_address): Call it on PARM_DECL bases.
	(verify_expr): Likewise, also verify SSA_NAME bases of MEM_REFs.
---
 gcc/tree-cfg.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 3385164..c917967 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -2764,6 +2764,23 @@ gimple_split_edge (edge edge_in)
   return new_bb;
 }
 
+/* Verify that a VAR, PARM_DECL or RESULT_DECL T is from the current function,
+   and if not, return true.  If it is, return false.  */
+
+static bool
+verify_var_parm_result_decl (tree t)
+{
+  tree context = decl_function_context (t);
+  if (context != cfun->decl
+      && !SCOPE_FILE_SCOPE_P (context)
+      && !TREE_STATIC (t)
+      && !DECL_EXTERNAL (t))
+    {
+      error ("Local declaration from a different function");
+      return true;
+    }
+  return NULL;
+}
 
 /* Verify properties of the address expression T with base object BASE.  */
 
@@ -2798,6 +2815,8 @@ verify_address (tree t, tree base)
 	|| TREE_CODE (base) == RESULT_DECL))
     return NULL_TREE;
 
+  if (verify_var_parm_result_decl (base))
+    return base;
   if (DECL_GIMPLE_REG_P (base))
     {
       error ("DECL_GIMPLE_REG_P set on a variable with address taken");
@@ -2834,6 +2853,13 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 	}
       break;
 
+    case PARM_DECL:
+    case VAR_DECL:
+    case RESULT_DECL:
+      if (verify_var_parm_result_decl (t))
+	return t;
+      break;
+
     case INDIRECT_REF:
       error ("INDIRECT_REF in gimple IL");
       return t;
@@ -2852,9 +2878,25 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 	  error ("invalid offset operand of MEM_REF");
 	  return TREE_OPERAND (t, 1);
 	}
+      if (TREE_CODE (x) == SSA_NAME)
+	{
+	  if (SSA_NAME_IN_FREE_LIST (x))
+	    {
+	      error ("SSA name in freelist but still referenced");
+	      return x;
+	    }
+	  if (SSA_NAME_VAR (x))
+	    x = SSA_NAME_VAR (x);;
+	}
+      if ((TREE_CODE (x) == PARM_DECL
+	   || TREE_CODE (x) == VAR_DECL
+	   || TREE_CODE (x) == RESULT_DECL)
+	  && verify_var_parm_result_decl (x))
+	return x;
       if (TREE_CODE (x) == ADDR_EXPR
 	  && (x = verify_address (x, TREE_OPERAND (x, 0))))
 	return x;
+
       *walk_subtrees = 0;
       break;
 
@@ -3010,6 +3052,11 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
 
 	  t = TREE_OPERAND (t, 0);
 	}
+      if ((TREE_CODE (t) == PARM_DECL
+	   || TREE_CODE (t) == VAR_DECL
+	   || TREE_CODE (t) == RESULT_DECL)
+	  && verify_var_parm_result_decl (t))
+	return t;
 
       if (!is_gimple_min_invariant (t) && !is_gimple_lvalue (t))
 	{
-- 
2.8.1


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