re PR middle-end/66568 ([CHKP] internal compiler error: in expand_expr_addr_expr_1)
authorIlya Enkovich <enkovich.gnu@gmail.com>
Thu, 18 Jun 2015 10:14:38 +0000 (10:14 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Thu, 18 Jun 2015 10:14:38 +0000 (10:14 +0000)
gcc/

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/

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

From-SVN: r224601

gcc/ChangeLog
gcc/cfgexpand.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/mpx/pr66568.c [new file with mode: 0644]
gcc/tree-chkp.c
gcc/tree-chkp.h

index 335ec7dbddce5f4565b05b1e34976b7d7741c00c..23301d4beee43d6ff7fddfed96283ea76dec2c1b 100644 (file)
@@ -1,3 +1,11 @@
+2015-06-18  Ilya Enkovich  <enkovich.gnu@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.
+
 2015-06-18  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        PR middle-end/66567
index 06755d5491c82d7115d263d30c2cfac18effe0bc..6b79b1dae77831930d12318f1b23e9c3b53d4a85 100644 (file)
@@ -3134,18 +3134,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
@@ -3154,15 +3161,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);
            }
        }
@@ -3259,33 +3274,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:
index 95107ae6681c04bb02eddacce5f3078a6cd0a57f..3b1d0710c1a93b151263375ece3d8a3b4d8cd889 100644 (file)
@@ -1,3 +1,8 @@
+2015-06-18  Ilya Enkovich  <enkovich.gnu@gmail.com>
+
+       PR middle-end/66568
+       * gcc.target/i386/mpx/pr66568.c: New test.
+
 2015-06-18  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        PR middle-end/66567
diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr66568.c b/gcc/testsuite/gcc.target/i386/mpx/pr66568.c
new file mode 100644 (file)
index 0000000..d7bb9f6
--- /dev/null
@@ -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;
+}
index ed734e649c4062d7ffe0732223926c99cc1a277e..7ffec7b630574b7144522619e489c9d508bdfff6 100644 (file)
@@ -466,6 +466,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)
index b5ab56252ed3d293a3f2a435d0a6978abbf50571..6e41086ebe4d78af82ccdc8336b181d712e90408 100644 (file)
@@ -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);