Fixed a bug in expansion of array notations in if-statement conditions.
authorBalaji V. Iyer <balaji.v.iyer@intel.com>
Mon, 3 Jun 2013 22:28:09 +0000 (22:28 +0000)
committerBalaji V. Iyer <bviyer@gcc.gnu.org>
Mon, 3 Jun 2013 22:28:09 +0000 (15:28 -0700)
2013-06-03  Balaji V. Iyer  <balaji.v.iyer@intel.com>

       * c-typeck.c (c_finish_if_stmt): Added a check to see if the rank of the
       condition of the if-statement matches the rank of else-block and then-
       block when array notations are used.
       * c-parser.c (c_parser_declaration_or_fndef): Expanded array notation
       expression after the entire function body is parsed.
       (c_parser_expr_no_commas): Delayed creating array notation expressions
       to the end of function parsing.
       * c-array-notation.c (fix_conditional_array_notations_1): Expanded the
       whole if-statement instead of just the condition.
       (expand_array_notation_exprs): Added MODIFY_EXPR case.

2013-06-03  Balaji V. Iyer  <balaji.v.iyer@intel.com>

       * c-c++-common/cilk-plus/AN/if_test_errors.c (main): New testcase.
       * c-c++-common/cilk-plus/AN/rank_mismatch.c: Added a '-w' option to
       dg-option and an header comment.

From-SVN: r199628

gcc/c/ChangeLog
gcc/c/c-array-notation.c
gcc/c/c-parser.c
gcc/c/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c

index 437be91..48be2fd 100644 (file)
@@ -1,5 +1,18 @@
 2013-06-03  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
+       * c-typeck.c (c_finish_if_stmt): Added a check to see if the rank of the
+       condition of the if-statement matches the rank of else-block and then-
+       block when array notations are used.
+       * c-parser.c (c_parser_declaration_or_fndef): Expanded array notation
+       expression after the entire function body is parsed.
+       (c_parser_expr_no_commas): Delayed creating array notation expressions
+       to the end of function parsing.
+       * c-array-notation.c (fix_conditional_array_notations_1): Expanded the
+       whole if-statement instead of just the condition.
+       (expand_array_notation_exprs): Added MODIFY_EXPR case.  
+
+2013-06-03  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
        PR c/57474
        * c-array-notation.c (build_array_notation_expr): Initialized rhs_length
        array to NULL_TREE if they are unused.  Also added a check for the
index 0807466..bcd0922 100644 (file)
@@ -1879,7 +1879,7 @@ fix_conditional_array_notations_1 (tree stmt)
   if (!find_rank (location, cond, cond, false, &rank))
     return error_mark_node;
   
-  extract_array_notation_exprs (cond, false, &array_list);
+  extract_array_notation_exprs (stmt, false, &array_list);
   loop_init = push_stmt_list ();
   for (ii = 0; ii < vec_safe_length (array_list); ii++)
     { 
@@ -1899,12 +1899,12 @@ fix_conditional_array_notations_1 (tree stmt)
              vec_safe_push (sub_list, array_node);
              vec_safe_push (new_var_list, new_var);
              add_stmt (builtin_loop);
-             replace_array_notations (&cond, false, sub_list, new_var_list); 
+             replace_array_notations (&stmt, false, sub_list, new_var_list); 
            }
        }
     }
 
-  if (!find_rank (location, cond, cond, true, &rank))
+  if (!find_rank (location, stmt, stmt, true, &rank))
     {
       pop_stmt_list (loop_init);
       return error_mark_node;
@@ -1915,7 +1915,7 @@ fix_conditional_array_notations_1 (tree stmt)
       pop_stmt_list (loop_init); 
       return loop_init;
     }  
-  extract_array_notation_exprs (cond, true, &array_list);
+  extract_array_notation_exprs (stmt, true, &array_list);
 
   if (vec_safe_length (array_list) == 0)
     return stmt;
@@ -2765,6 +2765,18 @@ expand_array_notation_exprs (tree t)
            expand_array_notation_exprs (*tsi_stmt_ptr (ii_tsi));
       }
       return t;
+    case MODIFY_EXPR:
+      {
+       location_t loc = EXPR_HAS_LOCATION (t) ? EXPR_LOCATION (t) :
+         UNKNOWN_LOCATION;
+       tree lhs = TREE_OPERAND (t, 0);
+       tree rhs = TREE_OPERAND (t, 1);
+       location_t rhs_loc = EXPR_HAS_LOCATION (rhs) ? EXPR_LOCATION (rhs) :
+         UNKNOWN_LOCATION;
+       t = build_array_notation_expr (loc, lhs, TREE_TYPE (lhs), NOP_EXPR,
+                                      rhs_loc, rhs, TREE_TYPE (rhs));
+       return t;
+      }
     case CALL_EXPR:
       t = fix_array_notation_call_expr (t);
       return t;
index b89d8c1..d6a500e 100644 (file)
@@ -1756,6 +1756,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
        = c_parser_peek_token (parser)->location;
       fnbody = c_parser_compound_statement (parser);
+      if (flag_enable_cilkplus && contains_array_notation_expr (fnbody))
+       fnbody = expand_array_notation_exprs (fnbody);
       if (nested)
        {
          tree decl = current_function_decl;
@@ -5445,20 +5447,9 @@ c_parser_expr_no_commas (c_parser *parser, struct c_expr *after)
   rhs = c_parser_expr_no_commas (parser, NULL);
   rhs = default_function_array_read_conversion (exp_location, rhs);
   
-  /* The line below is where the statement has the form:
-     A = B, where A and B contain array notation exprs. So this is where
-     we handle those.  */
-  if (flag_enable_cilkplus
-      && (contains_array_notation_expr (lhs.value)
-         || contains_array_notation_expr (rhs.value)))
-    ret.value = build_array_notation_expr (op_location, lhs.value,
-                                          lhs.original_type, code,
-                                          exp_location, rhs.value,
-                                          rhs.original_type);
-  else
-    ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
-                                  code, exp_location, rhs.value,
-                                  rhs.original_type);
+  ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
+                                code, exp_location, rhs.value,
+                                rhs.original_type);
   if (code == NOP_EXPR)
     ret.original_code = MODIFY_EXPR;
   else
index 749c8e2..e5e1455 100644 (file)
@@ -8983,6 +8983,34 @@ c_finish_if_stmt (location_t if_locus, tree cond, tree then_block,
 {
   tree stmt;
 
+  /* If the condition has array notations, then the rank of the then_block and
+     else_block must be either 0 or be equal to the rank of the condition.  If
+     the condition does not have array notations then break them up as it is
+     broken up in a normal expression.  */
+  if (flag_enable_cilkplus && contains_array_notation_expr (cond))
+    {
+      size_t then_rank = 0, cond_rank = 0, else_rank = 0;
+      if (!find_rank (if_locus, cond, cond, true, &cond_rank))
+       return;
+      if (then_block
+         && !find_rank (if_locus, then_block, then_block, true, &then_rank))
+       return;
+      if (else_block
+         && !find_rank (if_locus, else_block, else_block, true, &else_rank)) 
+       return;
+      if (cond_rank != then_rank && then_rank != 0)
+       {
+         error_at (if_locus, "rank-mismatch between if-statement%'s condition"
+                   " and the then-block");
+         return;
+       }
+      else if (cond_rank != else_rank && else_rank != 0)
+       {
+         error_at (if_locus, "rank-mismatch between if-statement%'s condition"
+                   " and the else-block");
+         return;
+       }
+    }
   /* Diagnose an ambiguous else if if-then-else is nested inside if-then.  */
   if (warn_parentheses && nested_if && else_block == NULL)
     {
index a1f0827..e0f75fd 100644 (file)
@@ -1,3 +1,9 @@
+2013-06-03  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * c-c++-common/cilk-plus/AN/if_test_errors.c (main): New testcase.
+       * c-c++-common/cilk-plus/AN/rank_mismatch.c: Added a '-w' option to
+       dg-option and an header comment.
+       
 2013-06-03  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/57419
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c
new file mode 100644 (file)
index 0000000..d17d8cf
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+
+#include <stdlib.h>
+int main (void)
+{
+  int x = 3, y, z, array[10], array2[10], TwodArray[10][10], jj,kk,ll ;
+  int array2_check[10], array2d_check[10][10], array2d[10][10];
+  int FourDArray[10][10][10][10], array4[10][10][10][10];
+  int array4_check[10][10][10][10];
+  int ii = 0;
+
+  x = 5;
+  y = 10;
+  z = 2;
+
+  if (!array[:]) /* This is OK! */
+    array2[:] = 5;
+  else
+    array2[:] = 10;
+  if (!(array[0:10:1] + array[0:10:1])) /* { dg-error "condition and the then-block" } */
+    array2d[:][:] = 5;
+  else
+    array2[:] = 10;
+
+  if (!(array[0:10:1] + array[0:10:1])) /* { dg-error "condition and the else-block" } */
+    array2[:] = 5;
+  else
+    array2d[:][:] = 10;
+
+
+  if (TwodArray[:][:] != 10) /* { dg-error "condition and the then-block" } */
+    array2[:] = 10; 
+  else
+    array2[:] = 5;
+
+  if (FourDArray[43][:][:][:] != 10) /* This is OK!  */ 
+    array4[45][:][:][:] = 10; 
+  else
+    array4[32][:][:][:] = 5;
+
+  /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+  if (FourDArray[42][0:10:1][9:10:-1][0:5:2] != 10) /* { dg-error "condition and the then-block" } */
+    array4[0:10:1][0:5:2][9:10:-1][0:5:2] = 10; 
+  else
+    array4[0:10:1][0:5:2][9:10:-1][0:5:2] = 5;
+
+  /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+  if (FourDArray[0:10:1][0:5:2][9:10:-1][x:y:z] +
+      FourDArray[0:10:1][0:5:2][9:-10:1][x:y:z]  != 20) 
+    array4[0:10:1][0:5:2][9:10:-1][x:y:z] = 10; 
+  else
+    array4[0:10][0:5:2][9:10:-1][x:y:z] = 5;
+
+  return 0;
+}
index a8c9dab..b5e37ce 100644 (file)
@@ -1,7 +1,10 @@
 /* { dg-do compile } */
-/* { dg-options "-fcilkplus" } */
+/* { dg-options "-fcilkplus -w" } */
 
-int main (int argc, char **argv)
+/* We use -w because in the first error, there will be a warning of setting an
+   integer to a pointer.  Just ignore it to expose the rank mismatch error.  */
+
+int main (void)
 {
   int x = 0;
   int array[10][10], array2[10];