Hello Everyone,
        This patch is for Cilk Plus branch affecting mainly the C compiler. It 
checks to see if the gotos and increment expressions inside cilk_for are valid 
and report errors otherwise.

Thanks,

Balaji V. Iyer.
Index: gcc/c-family/c-cilk.c
===================================================================
--- gcc/c-family/c-cilk.c       (revision 194366)
+++ gcc/c-family/c-cilk.c       (working copy)
@@ -1292,8 +1292,9 @@
         them in code that spawns. */
       if ((TREE_CODE (arg) == VAR_DECL) && DECL_HARD_REGISTER (arg))
        {
-         error ("explicit register variable %qD may not be modified in spawn",
-                arg);
+         error_at (EXPR_LOCATION (arg),
+                   "explicit register variable %qD may not be modified in "
+                   "spawn", arg);
          arg = null_pointer_node;
        }
       else
@@ -1464,7 +1465,8 @@
       return copy_decl_no_change (decl, id);
 
     case LABEL_DECL:
-      error ("Invalid use of label %q+D in spawn", decl);
+      error_at (EXPR_LOCATION (decl),
+               "Invalid use of label %q+D in spawn", decl);
       return error_mark_node;
 
     case RESULT_DECL:
@@ -1544,7 +1546,8 @@
   if (! (flags & ECF_NOTHROW) && flag_exceptions)
     *throws = true;
   if (flags & ECF_RETURNS_TWICE)
-    error ("Can not spawn call to function that returns twice");
+    error_at (EXPR_LOCATION (t),
+             "Can not spawn call to function that returns twice");
   return 0;
 }
 
@@ -1761,6 +1764,7 @@
   tree cond = FOR_COND (loop);
   tree init = CILK_FOR_INIT (loop);
   tree incr = cilk_simplify_tree (FOR_EXPR (loop));
+  tree orig_incr = cilk_simplify_tree (FOR_EXPR (loop)); /* Copy for LOC.  */ 
   tree grain = CILK_FOR_GRAIN (loop);
   tree body = FOR_BODY (loop);
   
@@ -1937,9 +1941,12 @@
          exactly_one = incr_direction == -1;
        }
       else
-       gcc_unreachable ();
+       {
+         error_at (EXPR_LOCATION (orig_incr),
+                   "Invalid loop increment operation.");
+         cfd->invalid = true;
+       }
       break;
-
     default:
       gcc_unreachable ();
     }
@@ -2865,3 +2872,6 @@
     }
   return decl;
 }
+
+
+  
Index: gcc/c-family/ChangeLog.cilkplus
===================================================================
--- gcc/c-family/ChangeLog.cilkplus     (revision 194366)
+++ gcc/c-family/ChangeLog.cilkplus     (working copy)
@@ -1,3 +1,11 @@
+2012-12-12  Balaji V. Iyer  <balaji.v.i...@intel.com>
+
+       * c-typeck.c (c_finish_cilk_loop) Added location for error reporting.
+       * c-cilk.c (wrapper_parm_cb): Likewise.
+       (copy_decl_for_cilk): Likewise.
+       (check_outlined_calls): Likewise.
+       (extract_for_fields): Reported an error instead of gcc_unreachable ().
+
 2012-12-10  Balaji V. Iyer  <balaji.v.i...@intel.com>
 
        * c-cpp-elem-function.c: New file.
Index: gcc/c/c-typeck.c
===================================================================
--- gcc/c/c-typeck.c    (revision 194366)
+++ gcc/c/c-typeck.c    (working copy)
@@ -10982,19 +10982,19 @@
 
   if (!cond)
     {
-      error ("cilk_for missing condition");
+      error ("_Cilk_for missing condition");
       return;
     }
   if (!incr)
     {
-      error ("cilk_for missing increment");
+      error ("_Cilk_for missing increment");
       return;
     }
 
   /* If the condition is zero don't generate a loop construct.  */
   if (TREE_CONSTANT (cond))
     {
-      error ("cilk_for has constant condition");
+      error_at (EXPR_LOCATION (cond), "_Cilk_for has constant condition");
       return;
     }
   if (!cvar)
@@ -11004,7 +11004,7 @@
     }
   if (clab)
     {
-      error ("cilk_for has continue");
+      error_at (EXPR_LOCATION (clab), "_Cilk_for has continue");
       return;
     }
 
Index: gcc/c/c-objc-common.h
===================================================================
--- gcc/c/c-objc-common.h       (revision 194366)
+++ gcc/c/c-objc-common.h       (working copy)
@@ -120,4 +120,7 @@
 
 #undef LANG_HOOKS_ELEM_FN_CREATE_FN
 #define LANG_HOOKS_ELEM_FN_CREATE_FN elem_fn_create_fn
+
+#undef LANG_HOOKS_CILK_CHECK_CTRL_FLOW
+#define LANG_HOOKS_CILK_CHECK_CTRL_FLOW cilk_check_ctrl_flow
 #endif /* GCC_C_OBJC_COMMON */
Index: 
gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_incr_errors.c
===================================================================
--- 
gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_incr_errors.c 
    (revision 0)
+++ 
gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_incr_errors.c 
    (revision 0)
@@ -0,0 +1,22 @@
+#define ARRAY_SIZE 100000
+
+int main(void)
+{
+  int ii = 0;
+  int array[ARRAY_SIZE];
+  
+  _Cilk_for (ii = 0; ii < 10; ii <<= 2) /* { dg-error "Invalid loop increment 
operation." } */
+    array[ii] = 5;
+
+  _Cilk_for (ii = 0; ii < 10; ii *= 2) /* { dg-error "Invalid loop increment 
operation." } */
+    array[ii] = 5;
+
+  _Cilk_for (ii = 0; ii < 10; ii /= 2) /* { dg-error "Invalid loop increment 
operation." } */
+    array[ii] = 5;
+
+  _Cilk_for (ii = 0; ii < 10; ii = 5) /* { dg-error "Invalid loop increment 
operation." } */
+    array[ii] = 5;
+
+  _Cilk_for (ii = 0; ii < 10; ii >>= 2) /* { dg-error "Invalid loop increment 
operation." } */
+    array[ii] = 5;
+}
Index: gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/errors.exp
===================================================================
--- gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/errors.exp 
(revision 0)
+++ gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/errors.exp 
(revision 0)
@@ -0,0 +1,59 @@
+#   Copyright (C) 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# Written by Balaji V. Iyer <balaji.v.i...@intel.com>
+
+if { ![istarget i?86*-*-*] && ![istarget x86_64-*-*] } then {
+      return
+}
+
+
+load_lib gcc-dg.exp
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O0" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O1" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O2" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O3" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O0 -g" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O1 -g" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O2 -g" " "
+dg-finish
+
+dg-init
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] " -ldl 
-lcilkrts -I $srcdir/../../libcilkrts/include -std=c99 -fcilkplus -O3 -g" " "
+dg-finish
+
+dg-finish
+
Index: 
gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/goto_inside_cilkfor.c
===================================================================
--- 
gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/goto_inside_cilkfor.c  
    (revision 0)
+++ 
gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/goto_inside_cilkfor.c  
    (revision 0)
@@ -0,0 +1,49 @@
+/* Checks goto inside cilk_for and outside of cilk_for.  */
+
+#define ARRAY_SIZE 10000
+int a[ARRAY_SIZE], b[ARRAY_SIZE][ARRAY_SIZE];
+int main (int argc, char **argv)
+{
+    int i = 0, q = 0, j = 0;
+    _Cilk_for (i = 0; i < ARRAY_SIZE; i++)
+    {
+l1:
+       a[i] = i;
+l2:
+       if (i%2)
+         q+=2;
+    }
+    goto l1; /* { dg-error "Goto label is inside a _Cilk_for while the goto 
itself is outside." }   */
+    if(a[(ARRAY_SIZE / 2)] == (ARRAY_SIZE / 2))
+        goto l2; /* { dg-error "Goto label is inside a _Cilk_for while the 
goto itself is outside." } */
+
+    _Cilk_for (i = 0; i < ARRAY_SIZE; i++)
+    {
+      /* Goto jumps into another Cilk_for.  */
+        goto l2; /* { dg-error "goto destination is outside the _Cilk_for 
scope." }  */
+       a[i] = i;
+l3:
+       goto l3; /* This is OK!  */
+    }
+    if(a[(ARRAY_SIZE / 2)] == (ARRAY_SIZE / 2))
+      goto l4; /* This is OK!  */
+    else
+        goto l3; /* { dg-error "Goto label is inside a _Cilk_for while the 
goto itself is outside." } */
+
+    _Cilk_for (i = 0; i < ARRAY_SIZE; i++) {
+l5:
+       if (i % 5) {
+           _Cilk_for (j = 0; j < ARRAY_SIZE; j++) {
+               goto l5; /* { dg-error "goto destination is outside the 
_Cilk_for scope." } */
+               b[i][j] = (i+j);
+l6:
+             q++;
+             goto l6; /* This is OK!  */
+           }
+           goto l6; /* { dg-error "goto destination is outside the _Cilk_for 
scope." } */
+       }
+    }
+
+l4:
+    return 0;
+}
Index: gcc/testsuite/ChangeLog.cilkplus
===================================================================
--- gcc/testsuite/ChangeLog.cilkplus    (revision 194366)
+++ gcc/testsuite/ChangeLog.cilkplus    (working copy)
@@ -1,3 +1,11 @@
+2012-12-12  Balaji V. Iyer  <balaji.v.i...@intel.com>
+
+       * gcc.dg/cilk-plus/cilk_keywords_test/errors/goto_inside_cilkfor.c: 
+       New test.
+       * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_incr_errors.c:
+       Likewise.
+       * gcc.dg/cilk-plus/cilk_keywords_test/errors/errors.exp: New script.
+
 2012-12-10  Balaji V. Iyer  <balaji.v.i...@intel.com>
 
        * gcc.dg/cilk-plus/elem_fn_tests/test1.c: Remove.
Index: gcc/cilk.c
===================================================================
--- gcc/cilk.c  (revision 194366)
+++ gcc/cilk.c  (working copy)
@@ -37,6 +37,16 @@
 #include "output.h"
 #include "dwarf2out.h"
 
+
+/* The only reason why we have this struct is that we need a void * to pass
+   into the walk_tree function.  */
+
+struct label_list_struct
+{
+  vec <tree, va_gc> *labels;
+};
+
+
 tree cilk_trees[(int) CILK_TI_MAX];
 
 static HOST_WIDE_INT worker_tail_offset;
@@ -1406,3 +1416,150 @@
     return true;
   return false;
 }
+
+
+/* Helper function for walk_trees.  *WALK_SUBTREES is seto to zero if it
+   encounters a CILK_FOR, LABEL_DECL or GOTO in *TP.  If LABEL_DECL is found
+   then the value is pushed into the list pointed by DATA.  */
+
+static tree
+store_labels (tree *tp, int *walk_subtrees, void *data)
+{
+  struct label_list_struct *label_list = (struct label_list_struct *)data;
+
+  if (!tp || !*tp)
+    return NULL_TREE;
+  else if (TREE_CODE (*tp) == CILK_FOR_STMT
+          || TREE_CODE (*tp) == GOTO_EXPR)
+    *walk_subtrees = 0;
+  else if (TREE_CODE (*tp) == LABEL_DECL)
+    {
+      *walk_subtrees = 0;
+      vec_safe_push (label_list->labels, *tp);
+    }
+  else
+    *walk_subtrees = 1;
+  return NULL_TREE;
+}
+
+/* Finds all the labels in STMT that is not inside a CILK_FOR.  */
+
+static struct label_list_struct
+find_all_labels (tree stmt)
+{
+  struct label_list_struct label_list;
+
+  label_list.labels = NULL;
+  walk_tree (&stmt, store_labels, (void *)&label_list, NULL);
+  return label_list;
+}
+
+/* Helper function for walk_trees.  If the *TP is GOTO_EXPR it will check if 
+   its destination label is in the list in *DATA.  *WALK_SUBTREES is always 
+   set to one.  */
+
+static tree
+check_goto_labels_inside_cilk_for_body (tree *tp, int *walk_subtrees,
+                                       void *data)
+{
+  size_t ii = 0;
+  tree ii_t = NULL_TREE;
+  bool label_ok = false;
+  struct label_list_struct *label_list = (struct label_list_struct *)data;
+  if (!tp || !*tp)
+    return NULL_TREE;
+
+  if (TREE_CODE (*tp) == GOTO_EXPR)
+    {
+      tree goto_label = GOTO_DESTINATION (*tp);
+      for (ii = 0; vec_safe_iterate (label_list->labels, ii, &ii_t); ii++)
+       if (ii_t == goto_label)
+         label_ok = true;
+      
+      if (!label_ok)
+       {
+         error_at (EXPR_LOCATION (*tp), "goto destination is outside the "
+                   "_Cilk_for scope.");
+         *tp = error_mark_node;
+       }
+    }
+  else if (TREE_CODE (*tp) == CILK_FOR_STMT)
+    *walk_subtrees = 0;
+  else
+    *walk_subtrees = 1;
+  return NULL_TREE;
+}
+
+/* Helper function for walk_tree. If *TP is a CILK_FOR_STMT, then it will find
+   all the labels in it and then walks through the body to see if the gotos in
+   it are using the local labels.  */
+
+static tree
+check_gotos_inside_cilk_for (tree *tp, int *walk_subtrees,
+                            void *data ATTRIBUTE_UNUSED)
+{
+  struct label_list_struct label_list;
+  if (!tp || !*tp)
+    return NULL_TREE;
+
+  if (TREE_CODE (*tp) == CILK_FOR_STMT)
+    {
+      label_list = find_all_labels (FOR_BODY (*tp));
+      walk_tree (&FOR_BODY (*tp), check_goto_labels_inside_cilk_for_body,
+                (void *) &label_list, NULL);
+    }
+  *walk_subtrees = 1;
+  return NULL_TREE;
+}
+
+/* Helper function for walk_tree.  */
+
+static tree
+check_gotos_outside_cilk_for (tree *tp, int *walk_subtrees,
+                             void *data)
+{
+  tree ii_t = NULL_TREE;
+  size_t ii = 0;
+  bool label_ok = false;
+  struct label_list_struct *label_list = (struct label_list_struct *) data;
+  if (!tp || !*tp)
+    return NULL_TREE;
+
+  if (TREE_CODE (*tp) == GOTO_EXPR)
+    {
+      tree goto_label = GOTO_DESTINATION (*tp);
+      *walk_subtrees = 0;
+      for (ii = 0; vec_safe_iterate (label_list->labels, ii, &ii_t); ii++)
+       if (ii_t == goto_label)
+         label_ok = true;
+
+      if (!label_ok)
+       {
+         error_at (EXPR_LOCATION (*tp), "Goto label is inside a _Cilk_for "
+                   "while the goto itself is outside.");
+         *tp = error_mark_node;
+       }
+    }
+  else if (TREE_CODE (*tp) == CILK_FOR_STMT)
+    *walk_subtrees = 0;
+  else
+    *walk_subtrees = 1;
+
+  return NULL_TREE;
+}
+ 
+/* Checks some of the control flow changing statements (e.g. goto) in *FNBODY
+   are valid.  */
+
+void
+cilk_check_ctrl_flow (tree *fnbody)
+{
+  struct label_list_struct label_list;
+  if (!fnbody)
+    return;
+  walk_tree (fnbody, check_gotos_inside_cilk_for, NULL, NULL);
+
+  label_list = find_all_labels (*fnbody);
+  walk_tree (fnbody, check_gotos_outside_cilk_for, (void *) &label_list, NULL);
+  return;
+}
Index: gcc/cilk.h
===================================================================
--- gcc/cilk.h  (revision 194366)
+++ gcc/cilk.h  (working copy)
@@ -296,6 +296,7 @@
 void gimplify_cilk_spawn (tree *, gimple_seq *, gimple_seq *);
 void gimplify_cilk_sync (tree *, gimple_seq *);
 void gimplify_cilk_for (tree *, gimple_seq *, gimple_seq *);
+void cilk_check_ctrl_flow (tree *);
 extern tree cilk_call_setjmp (tree);
 extern tree make_cilk_frame (tree);
 extern tree build_cilk_function_exit (tree, bool, bool);
Index: gcc/ChangeLog.cilkplus
===================================================================
--- gcc/ChangeLog.cilkplus      (revision 194366)
+++ gcc/ChangeLog.cilkplus      (working copy)
@@ -1,3 +1,18 @@
+2012-12-12  Balaji V. Iyer  <balaji.v.i...@intel.com>
+
+       * c/c-objc-common.h (LANG_HOOKS_CILK_CHECK_CTRL_FLOW): New define.
+       * cilk.c (store_labels): New function.
+       (find_all_labels): Likewise.
+       (check_goto_labels_inside_cilk_for_body): Likewise.
+       (check_gotos_inside_cilk_for): Likewise.
+       (check_gotos_outside_cilk_for): Likewise.
+       (check_cilk_ctrl_flow): Likewise.
+       * langhooks.c (lhd_cilk_check_ctrl_flow): Likewise.
+       * langhooks.h (struct lang_hooks_for_cilkplus): New function pointer.
+       * gimplify.c (gimplify_function_tree): Called cilk_check_ctrl_flow
+       function that is part of lang_hooks.
+       * langhooks-def.h (LANG_HOOKS_CILK): New field added.
+
 2012-12-10  Balaji V. Iyer  <balaji.v.i...@intel.com>
 
        * doc/tm.texi (TARGET_CILKPLUS_BUILTIN_MAP_PROCESSOR_TO_ATTR): Added
Index: gcc/langhooks.c
===================================================================
--- gcc/langhooks.c     (revision 194366)
+++ gcc/langhooks.c     (working copy)
@@ -730,3 +730,8 @@
 {
   return;
 }
+
+void lhd_cilk_check_ctrl_flow (tree *x ATTRIBUTE_UNUSED)
+{
+  return;
+}
Index: gcc/langhooks.h
===================================================================
--- gcc/langhooks.h     (revision 194366)
+++ gcc/langhooks.h     (working copy)
@@ -235,6 +235,7 @@
   void (*gimplify_cilk_spawn) (tree *, gimple_seq *, gimple_seq *);
   void (*gimplify_cilk_for) (tree *, gimple_seq *, gimple_seq *);
   void (*gimplify_cilk_sync) (tree *, gimple_seq *);
+  void (*cilk_check_ctrl_flow) (tree *);
   void (*elem_fn_create_fn) (tree);
 };
 
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c      (revision 194366)
+++ gcc/gimplify.c      (working copy)
@@ -8415,6 +8415,8 @@
 
   gcc_assert (!gimple_body (fndecl));
 
+  if (flag_enable_cilk)
+    lang_hooks.cilkplus.cilk_check_ctrl_flow (&DECL_SAVED_TREE (fndecl));
 
   /* Here we check to see if we have a function with the attribute "vector."  
      If so, then we must clone it to masked/unmasked when apropriate.  */
Index: gcc/langhooks-def.h
===================================================================
--- gcc/langhooks-def.h (revision 194366)
+++ gcc/langhooks-def.h (working copy)
@@ -217,6 +217,7 @@
 void lhd_gimplify_cilk_for (tree *, gimple_seq *, gimple_seq *);
 void lhd_gimplify_cilk_sync (tree *, gimple_seq *);
 void lhd_elem_fn_create_fn (tree);
+void lhd_cilk_check_ctrl_flow (tree *);
 #define LANG_HOOKS_CILK_RECOGNIZE_SPAWN hook_bool_tree_false
 #define LANG_HOOKS_CILK_VALID_CTOR hook_bool_tree_false
 #define LANG_HOOKS_CILK_VALID_SPAWN lhd_cilk_valid_spawn
@@ -224,6 +225,7 @@
 #define LANG_HOOKS_GIMPLIFY_CILK_FOR   lhd_gimplify_cilk_for
 #define LANG_HOOKS_GIMPLIFY_CILK_SYNC  lhd_gimplify_cilk_sync
 #define LANG_HOOKS_ELEM_FN_CREATE_FN   lhd_elem_fn_create_fn
+#define LANG_HOOKS_CILK_CHECK_CTRL_FLOW lhd_cilk_check_ctrl_flow
 #define LANG_HOOKS_CILK {              \
   LANG_HOOKS_CILK_RECOGNIZE_SPAWN,     \
   LANG_HOOKS_CILK_VALID_CTOR,          \
@@ -231,6 +233,7 @@
   LANG_HOOKS_GIMPLIFY_CILK_SPAWN,              \
   LANG_HOOKS_GIMPLIFY_CILK_FOR,                \
   LANG_HOOKS_GIMPLIFY_CILK_SYNC,       \
+  LANG_HOOKS_CILK_CHECK_CTRL_FLOW,      \
   LANG_HOOKS_ELEM_FN_CREATE_FN          \
 }
 

Reply via email to