Hi,

Currently return statement with no bounds in instrumented function causes ICE.  
This patch uses zero bounds in such cases instead.  Bootstrapped and regtested 
for x86_64-unknown-linux-gnu.  Applied to trunk.  Is it OK for gcc-5-branch?

Thanks,
Ilya
--
gcc/

2015-06-18  Ilya Enkovich  <enkovich....@gmail.com>

        PR middle-end/66568
        * cfgexpand.c (expand_return): Handle missing bounds.
        (expand_gimple_stmt_1): Likewise.
        * tree-chkp.c (chkp_expand_zero_bounds): New.
        * tree-chkp.h (chkp_expand_zero_bounds): New.

gcc/testsuite/

2015-06-18  Ilya Enkovich  <enkovich....@gmail.com>

        PR middle-end/66568
        * gcc.target/i386/mpx/pr66568.c: New test.


diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index b23e325..7508b3f 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -3136,18 +3136,25 @@ expand_return (tree retval, tree bounds)
   bounds_rtl = DECL_BOUNDS_RTL (DECL_RESULT (current_function_decl));
   if (bounds_rtl)
     {
-      rtx addr, bnd;
+      rtx addr = NULL;
+      rtx bnd = NULL;
 
-      if (bounds)
+      if (bounds && bounds != error_mark_node)
        {
          bnd = expand_normal (bounds);
          targetm.calls.store_returned_bounds (bounds_rtl, bnd);
        }
       else if (REG_P (bounds_rtl))
        {
-         addr = expand_normal (build_fold_addr_expr (retval_rhs));
-         addr = gen_rtx_MEM (Pmode, addr);
-         bnd = targetm.calls.load_bounds_for_arg (addr, NULL, NULL);
+         if (bounds)
+           bnd = chkp_expand_zero_bounds ();
+         else
+           {
+             addr = expand_normal (build_fold_addr_expr (retval_rhs));
+             addr = gen_rtx_MEM (Pmode, addr);
+             bnd = targetm.calls.load_bounds_for_arg (addr, NULL, NULL);
+           }
+
          targetm.calls.store_returned_bounds (bounds_rtl, bnd);
        }
       else
@@ -3156,15 +3163,23 @@ expand_return (tree retval, tree bounds)
 
          gcc_assert (GET_CODE (bounds_rtl) == PARALLEL);
 
-         addr = expand_normal (build_fold_addr_expr (retval_rhs));
-         addr = gen_rtx_MEM (Pmode, addr);
+         if (bounds)
+           bnd = chkp_expand_zero_bounds ();
+         else
+           {
+             addr = expand_normal (build_fold_addr_expr (retval_rhs));
+             addr = gen_rtx_MEM (Pmode, addr);
+           }
 
          for (n = 0; n < XVECLEN (bounds_rtl, 0); n++)
            {
-             rtx offs = XEXP (XVECEXP (bounds_rtl, 0, n), 1);
              rtx slot = XEXP (XVECEXP (bounds_rtl, 0, n), 0);
-             rtx from = adjust_address (addr, Pmode, INTVAL (offs));
-             rtx bnd = targetm.calls.load_bounds_for_arg (from, NULL, NULL);
+             if (!bounds)
+               {
+                 rtx offs = XEXP (XVECEXP (bounds_rtl, 0, n), 1);
+                 rtx from = adjust_address (addr, Pmode, INTVAL (offs));
+                 bnd = targetm.calls.load_bounds_for_arg (from, NULL, NULL);
+               }
              targetm.calls.store_returned_bounds (slot, bnd);
            }
        }
@@ -3261,33 +3276,40 @@ expand_gimple_stmt_1 (gimple stmt)
       break;
 
     case GIMPLE_RETURN:
-      op0 = gimple_return_retval (as_a <greturn *> (stmt));
+      {
+       tree bnd = gimple_return_retbnd (as_a <greturn *> (stmt));
+       op0 = gimple_return_retval (as_a <greturn *> (stmt));
 
-      if (op0 && op0 != error_mark_node)
-       {
-         tree result = DECL_RESULT (current_function_decl);
+       if (op0 && op0 != error_mark_node)
+         {
+           tree result = DECL_RESULT (current_function_decl);
 
-         /* If we are not returning the current function's RESULT_DECL,
-            build an assignment to it.  */
-         if (op0 != result)
-           {
-             /* I believe that a function's RESULT_DECL is unique.  */
-             gcc_assert (TREE_CODE (op0) != RESULT_DECL);
-
-             /* ??? We'd like to use simply expand_assignment here,
-                but this fails if the value is of BLKmode but the return
-                decl is a register.  expand_return has special handling
-                for this combination, which eventually should move
-                to common code.  See comments there.  Until then, let's
-                build a modify expression :-/  */
-             op0 = build2 (MODIFY_EXPR, TREE_TYPE (result),
-                           result, op0);
-           }
-       }
-      if (!op0)
-       expand_null_return ();
-      else
-       expand_return (op0, gimple_return_retbnd (stmt));
+           /* If we are not returning the current function's RESULT_DECL,
+              build an assignment to it.  */
+           if (op0 != result)
+             {
+               /* I believe that a function's RESULT_DECL is unique.  */
+               gcc_assert (TREE_CODE (op0) != RESULT_DECL);
+
+               /* ??? We'd like to use simply expand_assignment here,
+                  but this fails if the value is of BLKmode but the return
+                  decl is a register.  expand_return has special handling
+                  for this combination, which eventually should move
+                  to common code.  See comments there.  Until then, let's
+                  build a modify expression :-/  */
+               op0 = build2 (MODIFY_EXPR, TREE_TYPE (result),
+                             result, op0);
+             }
+           /* Mark we have return statement with missing bounds.  */
+           if (!bnd && chkp_function_instrumented_p (cfun->decl))
+             bnd = error_mark_node;
+         }
+
+       if (!op0)
+         expand_null_return ();
+       else
+         expand_return (op0, bnd);
+      }
       break;
 
     case GIMPLE_ASSIGN:
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr66568.c 
b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c
new file mode 100644
index 0000000..d7bb9f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fcheck-pointer-bounds -mmpx -O2 -fPIC" } */
+
+int a, b, c;
+void *set_test () {
+  if (b)
+    a ? exit (0) : exit (1);
+  b = c;
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 8edef48..9b0b33c 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -468,6 +468,21 @@ chkp_gimple_call_builtin_p (gimple call,
   return false;
 }
 
+/* Emit code to build zero bounds and return RTL holding
+   the result.  */
+rtx
+chkp_expand_zero_bounds ()
+{
+  tree zero_bnd;
+
+  if (flag_chkp_use_static_const_bounds)
+    zero_bnd = chkp_get_zero_bounds_var ();
+  else
+    zero_bnd = chkp_build_make_bounds_call (integer_zero_node,
+                                           integer_zero_node);
+  return expand_normal (zero_bnd);
+}
+
 /* Emit code to store zero bounds for PTR located at MEM.  */
 void
 chkp_expand_bounds_reset_for_mem (tree mem, tree ptr)
diff --git a/gcc/tree-chkp.h b/gcc/tree-chkp.h
index b5ab562..6e41086 100644
--- a/gcc/tree-chkp.h
+++ b/gcc/tree-chkp.h
@@ -53,6 +53,7 @@ extern void chkp_copy_bounds_for_assign (gimple assign,
                                         struct cgraph_edge *edge);
 extern bool chkp_gimple_call_builtin_p (gimple call,
                                        enum built_in_function code);
+extern rtx chkp_expand_zero_bounds (void);
 extern void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr);
 extern tree chkp_insert_retbnd_call (tree bndval, tree retval,
                                     gimple_stmt_iterator *gsi);

Reply via email to