Hello Everyone,
This patch is for the C++ Compiler in the Cilkplus branch. This patch
will handle array notations inside conditional expressions.
Thanking You,
Yours Sincerely,
Balaji V. Iyer.
diff --git a/gcc/cp/ChangeLog.cilk b/gcc/cp/ChangeLog.cilk
index 3ba0406..06ef1ec 100644
--- a/gcc/cp/ChangeLog.cilk
+++ b/gcc/cp/ChangeLog.cilk
@@ -1,3 +1,11 @@
+2012-01-12 Balaji V. Iyer <balaji.v.i...@intel.com>
+
+ * cp-array-notation.c (fix_conditional_array_notations): New function.
+ (fix_conditional_array_notations_1): Likewise.
+ * parser.c (cp_parser_compound_statement): Added a call to
+ fix_conditional_array_notations.
+ * cp-tree.h: Added a prototype for fix_conditional_array_notations.
+
2012-01-11 Balaji V. Iyer <balaji.v.i...@intel.com>
* Make-lang.in: Added cp-array-notation.c file information.
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
index de1843a..dec87bb 100644
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -47,6 +47,7 @@
void replace_array_notations (tree *, tree *, tree *, int);
void find_rank (tree array, int *rank);
+static tree fix_conditional_array_notations_1 (tree stmt);
/* This function is to find the rank of an array notation expression.
* For example, an array notation of A[:][:] has a rank of 2.
@@ -623,3 +624,493 @@ build_x_array_notation_expr (tree lhs, enum tree_code
modifycode, tree rhs,
return loop;
}
+
+static tree
+fix_conditional_array_notations_1 (tree stmt)
+{
+ tree *array_list = NULL;
+ int list_size = 0;
+ tree cond = NULL;
+ int rank = 0, ii = 0, jj = 0;
+ tree **array_ops, *array_var, *array_operand, jj_tree, loop;
+ tree **array_value, **array_stride, **array_length, **array_start;
+ tree *body_label, *body_label_expr, *exit_label, *exit_label_expr;
+ tree *compare_expr, *if_stmt_label, *expr_incr, *ind_init;
+ bool **count_down, **array_vector;
+
+ if (TREE_CODE (stmt) == COND_EXPR)
+ cond = COND_EXPR_COND (stmt);
+ else if (TREE_CODE (stmt) == IF_STMT)
+ cond = IF_COND (stmt);
+ else if (TREE_CODE (stmt) == SWITCH_STMT)
+ cond = SWITCH_STMT_COND (stmt);
+ else if (TREE_CODE (stmt) == SWITCH_EXPR)
+ cond = SWITCH_COND (stmt);
+ else if (TREE_CODE (stmt) == WHILE_STMT)
+ cond = WHILE_COND (stmt);
+ else if (TREE_CODE (stmt) == FOR_STMT || TREE_CODE (stmt) == CILK_FOR_STMT)
+ cond = FOR_COND (stmt);
+ else if (TREE_CODE (stmt) == DO_STMT)
+ cond = DO_COND (stmt);
+ else
+ /* otherwise don't even touch the statement */
+ return stmt;
+
+ find_rank (cond, &rank);
+ if (rank == 0)
+ return stmt;
+
+ extract_array_notation_exprs (cond, &array_list, &list_size);
+
+ if (*array_list == NULL_TREE || list_size == 0)
+ return stmt;
+
+ array_ops = (tree **) xmalloc (sizeof (tree *) * list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_ops[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+
+ array_vector = (bool **) xmalloc (sizeof (bool *) * list_size);
+ for (ii = 0; ii < list_size; ii++)
+ array_vector[ii] = (bool *) xmalloc (sizeof (bool) * rank);
+
+ array_value = (tree **) xmalloc (sizeof (tree *) * list_size);
+ array_stride = (tree **) xmalloc (sizeof (tree *) * list_size);
+ array_length = (tree **) xmalloc (sizeof (tree *) * list_size);
+ array_start = (tree **) xmalloc (sizeof (tree *) * list_size);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ array_value[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ array_stride[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ array_length[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ array_start[ii] = (tree *) xmalloc (sizeof (tree) * rank);
+ }
+
+ body_label = (tree *) xmalloc(sizeof (tree) * rank);
+ body_label_expr = (tree *) xmalloc (sizeof (tree) * rank);
+ exit_label = (tree *) xmalloc (sizeof (tree) * rank);
+ exit_label_expr = (tree *) xmalloc (sizeof (tree) * rank);
+ compare_expr = (tree *) xmalloc (sizeof (tree) * rank);
+ if_stmt_label = (tree *) xmalloc (sizeof (tree) * rank);
+
+ expr_incr = (tree *) xmalloc (sizeof (tree) * rank);
+ ind_init = (tree *) xmalloc (sizeof (tree) * rank);
+
+ count_down = (bool **) xmalloc (sizeof (bool *) * list_size);
+ for (ii = 0; ii < list_size; ii++)
+ count_down[ii] = (bool *) xmalloc (sizeof (bool) * rank);
+
+ array_operand = (tree *) xmalloc (sizeof (tree) * list_size);
+
+ array_var = (tree *) xmalloc (sizeof (tree) * rank);
+
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ jj = 0;
+ for (jj_tree = array_list[ii];
+ jj_tree && TREE_CODE (jj_tree) == ARRAY_NOTATION_REF;
+ jj_tree = ARRAY_NOTATION_ARRAY (jj_tree))
+ {
+ array_ops[ii][jj] = jj_tree;
+ jj++;
+ }
+ }
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (TREE_CODE (array_list[ii]) == ARRAY_NOTATION_REF)
+ {
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (TREE_CODE (array_ops[ii][jj]) == ARRAY_NOTATION_REF)
+ {
+ array_value[ii][jj] =
+ ARRAY_NOTATION_ARRAY (array_ops[ii][jj]);
+ array_start[ii][jj] =
+ ARRAY_NOTATION_START (array_ops[ii][jj]);
+ array_length[ii][jj] =
+ ARRAY_NOTATION_LENGTH (array_ops[ii][jj]);
+ array_stride[ii][jj] =
+ ARRAY_NOTATION_STRIDE (array_ops[ii][jj]);
+ array_vector[ii][jj] = true;
+
+ if (!TREE_CONSTANT (array_length[ii][jj]))
+ count_down[ii][jj] = false;
+ else if (tree_int_cst_lt
+ (array_length[ii][jj],
+ build_int_cst (TREE_TYPE (array_length[ii][jj]),
+ 0)))
+ count_down[ii][jj] = true;
+ else
+ count_down[ii][jj] = false;
+ }
+ else
+ array_vector[ii][jj] = false;
+ }
+ }
+ }
+
+ loop = alloc_stmt_list();
+
+ for (ii = 0; ii < rank; ii++)
+ {
+
+ array_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
+ integer_type_node);
+ ind_init[ii] =
+ build_modify_expr (UNKNOWN_LOCATION, array_var[ii],
+ TREE_TYPE (array_var[ii]), NOP_EXPR,
+ UNKNOWN_LOCATION,
+ build_int_cst (TREE_TYPE (array_var[ii]), 0),
+ TREE_TYPE (array_var[ii]));
+
+ }
+
+ for (ii = 0; ii < rank ; ii++)
+ {
+ /* this will create the if statement label */
+ if_stmt_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (if_stmt_label[ii]) = current_function_decl;
+ DECL_ARTIFICIAL (if_stmt_label[ii]) = 0;
+ DECL_IGNORED_P (if_stmt_label[ii]) = 1;
+
+ /* this label statment will point to the loop body */
+ body_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (body_label[ii]) = current_function_decl;
+ DECL_ARTIFICIAL (body_label[ii]) = 0;
+ DECL_IGNORED_P (body_label[ii]) = 1;
+ body_label_expr[ii] = build1 (LABEL_EXPR, void_type_node,
body_label[ii]);
+
+ /* this will create the exit label..i.e. where the while loop will branch
+ out of
+ */
+ exit_label[ii] = build_decl (UNKNOWN_LOCATION, LABEL_DECL, NULL_TREE,
+ void_type_node);
+ DECL_CONTEXT (exit_label[ii]) = current_function_decl;
+ DECL_ARTIFICIAL (exit_label[ii]) = 0;
+ DECL_IGNORED_P (exit_label[ii]) = 1;
+ exit_label_expr[ii] = build1 (LABEL_EXPR, void_type_node,
exit_label[ii]);
+ }
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ if (array_vector[ii][0])
+ {
+ array_operand[ii] = array_value[ii][rank - 1];
+ gcc_assert (array_operand[ii]);
+
+ for (jj = rank - 1; jj >= 0; jj--)
+ {
+ if (count_down[ii][jj])
+ {
+ /* Array[start_index - (induction_var * stride)] */
+ array_operand[ii] = build_array_ref
+ (UNKNOWN_LOCATION, array_operand[ii],
+ build2 (MINUS_EXPR, TREE_TYPE (array_var[jj]),
+ array_start[ii][jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_var[jj], array_stride[ii][jj])));
+ }
+ else
+ {
+ /* Array[start_index + (induction_var * stride)] */
+ array_operand[ii] = build_array_ref
+ (UNKNOWN_LOCATION, array_operand[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[jj]),
+ array_start[ii][jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_var[jj], array_stride[ii][jj])));
+ }
+ }
+ }
+ }
+ replace_array_notations (&stmt, array_list, array_operand, list_size);
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ expr_incr[ii] =
+ build2 (MODIFY_EXPR, void_type_node, array_var[ii],
+ build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
+ build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+ }
+
+ for (jj = 0; jj < rank; jj++)
+ {
+ if (rank && expr_incr[jj])
+ {
+ if (count_down[0][jj])
+ compare_expr[jj] =
+ build2 (LT_EXPR, boolean_type_node, array_var[jj],
+ build2 (MULT_EXPR, TREE_TYPE (array_var[jj]),
+ array_length[0][jj],
+ build_int_cst (TREE_TYPE (array_var[jj]), -1)));
+ else
+ compare_expr[jj] = build2 (LT_EXPR, boolean_type_node,
+ array_var[jj], array_length[0][jj]);
+ }
+ }
+
+ for (ii = 0; ii < rank; ii++)
+ {
+ append_to_statement_list (ind_init [ii], &loop);
+
+ append_to_statement_list
+ (build1 (LABEL_EXPR, void_type_node, if_stmt_label[ii]), &loop);
+ append_to_statement_list
+ (build3 (COND_EXPR, void_type_node, compare_expr[ii],
+ build1 (GOTO_EXPR, void_type_node, body_label[ii]),
+ build1 (GOTO_EXPR, void_type_node, exit_label[ii])), &loop);
+ append_to_statement_list (body_label_expr[ii], &loop);
+ }
+
+ append_to_statement_list (stmt, &loop);
+
+ for (ii = rank - 1; ii >= 0; ii--)
+ {
+ append_to_statement_list (expr_incr[ii], &loop);
+ append_to_statement_list
+ (build1 (GOTO_EXPR, void_type_node, if_stmt_label[ii]), &loop);
+ append_to_statement_list (exit_label_expr[ii], &loop);
+ }
+
+ free (body_label);
+ free (body_label_expr);
+ free (exit_label);
+ free (exit_label_expr);
+ free (compare_expr);
+ free (if_stmt_label);
+ free (expr_incr);
+ free (ind_init);
+ free (array_operand);
+ free (array_var);
+
+ for (ii = 0; ii < list_size; ii++)
+ {
+ free (count_down[ii]);
+ free (array_value[ii]);
+ free (array_stride[ii]);
+ free (array_length[ii]);
+ free (array_start[ii]);
+ free (array_ops[ii]);
+ free (array_vector[ii]);
+ }
+
+ free (count_down);
+ free (array_value);
+ free (array_stride);
+ free (array_length);
+ free (array_start);
+ free (array_ops);
+ free (array_vector);
+
+ return loop;
+}
+
+/* This function will recursively go through all the subtrees and find all
+ * if, switch, for, while and do-while loops and fix up their conditions and
+ * also walk through their subtrees.
+ */
+tree
+fix_conditional_array_notations (tree t)
+{
+ enum tree_code code;
+ bool is_expr;
+
+ /* Skip empty subtrees. */
+ if (!t)
+ return t;
+
+ code = TREE_CODE (t);
+ is_expr = IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code));
+
+ switch (code)
+ {
+ case ERROR_MARK:
+ case IDENTIFIER_NODE:
+ case INTEGER_CST:
+ case REAL_CST:
+ case FIXED_CST:
+ case STRING_CST:
+ case BLOCK:
+ case PLACEHOLDER_EXPR:
+ case FIELD_DECL:
+ case VOID_TYPE:
+ case REAL_TYPE:
+ case SSA_NAME:
+ case LABEL_DECL:
+ case RESULT_DECL:
+ case VAR_DECL:
+ case PARM_DECL:
+ case NON_LVALUE_EXPR:
+ case CONVERT_EXPR:
+ case NOP_EXPR:
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ case PREDECREMENT_EXPR:
+ case PREINCREMENT_EXPR:
+ case POSTDECREMENT_EXPR:
+ case POSTINCREMENT_EXPR:
+ case ADDR_EXPR:
+ case ARRAY_REF:
+ case BIT_FIELD_REF:
+ case VECTOR_CST:
+ case COMPLEX_CST:
+ return t;
+
+ case CONSTRUCTOR:
+ return t;
+ case BIND_EXPR:
+ {
+ BIND_EXPR_BODY (t) =
+ fix_conditional_array_notations (BIND_EXPR_BODY (t));
+ return t;
+ }
+
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (t); !tsi_end_p (i); tsi_next (&i))
+ *tsi_stmt_ptr (i) =
+ fix_conditional_array_notations (*tsi_stmt_ptr (i));
+ return t;
+ }
+
+ case OMP_PARALLEL:
+ case OMP_TASK:
+ case OMP_FOR:
+ case OMP_SINGLE:
+ case OMP_SECTION:
+ case OMP_SECTIONS:
+ case OMP_MASTER:
+ case OMP_ORDERED:
+ case OMP_CRITICAL:
+ case OMP_ATOMIC:
+ case OMP_CLAUSE:
+ case TARGET_EXPR:
+ case RETURN_EXPR:
+ case DECL_EXPR:
+ case INTEGER_TYPE:
+ case ENUMERAL_TYPE:
+ case BOOLEAN_TYPE:
+ case POINTER_TYPE:
+ case ARRAY_TYPE:
+ case RECORD_TYPE:
+ case METHOD_TYPE:
+ case AGGR_INIT_EXPR:
+ case CALL_EXPR:
+ return t;
+
+ case COND_EXPR:
+ t = fix_conditional_array_notations_1 (t);
+ if (TREE_CODE (t) == COND_EXPR)
+ {
+ COND_EXPR_THEN (t) =
+ fix_conditional_array_notations (COND_EXPR_THEN (t));
+ COND_EXPR_ELSE (t) =
+ fix_conditional_array_notations (COND_EXPR_ELSE (t));
+ }
+ else
+ t = fix_conditional_array_notations (t);
+ return t;
+
+ case SWITCH_EXPR:
+ t = fix_conditional_array_notations_1 (t);
+ if (TREE_CODE (t) == SWITCH_EXPR)
+ SWITCH_BODY (t) = fix_conditional_array_notations (SWITCH_BODY (t));
+ else
+ t = fix_conditional_array_notations (t);
+ return t;
+
+ case FOR_STMT:
+ case CILK_FOR_STMT:
+ t = fix_conditional_array_notations_1 (t);
+
+ /* If the above function added some extra instructions above the original
+ * for statement, then we can't assume it is still FOR_STMT/CILK_FOR_STMT
+ * so we have to check again */
+ if (TREE_CODE (t) == CILK_FOR_STMT || TREE_CODE (t) == FOR_STMT)
+ FOR_BODY (t) = fix_conditional_array_notations (FOR_BODY (t));
+ else
+ t = fix_conditional_array_notations (t);
+ return t;
+
+ case IF_STMT:
+ t = fix_conditional_array_notations_1 (t);
+ /* If the above function added some extra instructions above the original
+ * if statement, then we can't assume it is still IF_STMT
+ * so we have to check again */
+ if (TREE_CODE (t) == IF_STMT)
+ {
+ if (THEN_CLAUSE (t))
+ THEN_CLAUSE (t) = fix_conditional_array_notations (THEN_CLAUSE (t));
+ if (ELSE_CLAUSE (t))
+ ELSE_CLAUSE (t) = fix_conditional_array_notations (ELSE_CLAUSE (t));
+ }
+ else
+ t = fix_conditional_array_notations (t);
+ return t;
+
+ case SWITCH_STMT:
+ t = fix_conditional_array_notations_1 (t);
+ /* If the above function added some extra instructions above the original
+ * switch statement, then we can't assume it is still SWITCH_STMT
+ * so we have to check again */
+ if (TREE_CODE (t) == SWITCH_STMT)
+ {
+ if (SWITCH_STMT_BODY (t))
+ SWITCH_STMT_BODY (t) =
+ fix_conditional_array_notations (SWITCH_STMT_BODY (t));
+ }
+ else
+ t = fix_conditional_array_notations (t);
+ return t;
+
+ case WHILE_STMT:
+ t = fix_conditional_array_notations_1 (t);
+ /* If the above function added some extra instructions above the original
+ * while statement, then we can't assume it is still WHILE_STMT
+ * so we have to check again */
+ if (TREE_CODE (t) == WHILE_STMT)
+ {
+ if (WHILE_BODY (t))
+ WHILE_BODY (t) = fix_conditional_array_notations (WHILE_BODY (t));
+ }
+ else
+ t = fix_conditional_array_notations (t);
+ return t;
+
+ case DO_STMT:
+ t = fix_conditional_array_notations_1 (t);
+ /* If the above function added some extra instructions above the original
+ * do-while statement, then we can't assume it is still DO_STMT
+ * so we have to check again */
+ if (TREE_CODE (t) == DO_STMT)
+ {
+ if (DO_BODY (t))
+ DO_BODY (t) = fix_conditional_array_notations (DO_BODY (t));
+ }
+ else
+ t = fix_conditional_array_notations (t);
+ return t;
+
+ default:
+ if (is_expr)
+ {
+ int i, len;
+
+ /* Walk over all the sub-trees of this operand. */
+ len = TREE_CODE_LENGTH (code);
+
+ /* Go through the subtrees. We need to do this in forward order so
+ that the scope of a FOR_EXPR is handled properly. */
+ for (i = 0; i < len; ++i)
+ TREE_OPERAND (t, i) =
+ fix_conditional_array_notations (TREE_OPERAND (t, i));
+ }
+ return t;
+ }
+ return t;
+}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d7cbefa..eae4550 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6026,6 +6026,7 @@ extern void gimplify_cilk_spawn (tree *,
gimple_seq *,
/* In cp/cp-array-notations.c */
extern tree build_x_array_notation_expr (tree, enum tree_code, tree,
tsubst_flags_t);
+extern tree fix_conditional_array_notations (tree);
/* -- end of C++ */
#endif /* ! GCC_CP_TREE_H */
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 9541b0e..c06eb7c 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -9121,6 +9121,7 @@ cp_parser_compound_statement (cp_parser *parser, tree
in_statement_expr,
/* Consume the `}'. */
cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
+ compound_stmt = fix_conditional_array_notations (compound_stmt);
return compound_stmt;
}
diff --git a/gcc/testsuite/ChangeLog.cilk b/gcc/testsuite/ChangeLog.cilk
index 64a8fe3..80a004a 100644
--- a/gcc/testsuite/ChangeLog.cilk
+++ b/gcc/testsuite/ChangeLog.cilk
@@ -1,3 +1,9 @@
+2012-01-12 Balaji V. Iyer <balaji.v.i...@intel.com>
+
+ * g++.dg/cilk-plus/array_notation_tests/switch_test.cc: New
+ * g++.dg/cilk-plus/array_notation_tests/if_test1.cc: Likewise.
+ * g++.dg/cilk-plus/array_notation_tests/if_test2.cc: Likewise.
+
2012-01-11 Balaji V. Iyer <balaji.v.i...@intel.com>
* g++.dg/cilk-plus/array_notation_tests/array_test1.cc: New.
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/if_test1.cc
b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/if_test1.cc
new file mode 100644
index 0000000..33f68d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/if_test1.cc
@@ -0,0 +1,38 @@
+#if HAVE_IO
+#include <iostream>
+#include <cstdlib>
+#endif
+int main(int argc, char **argv)
+{
+ int array[10], x;
+#if 1
+ for (int ii = 0; ii < 10; ii++)
+ array[ii] = 0;
+
+ array[:] = 19383;
+#endif
+ if (array[1] != 0) {
+ if (array[2] != 0) {
+ if (array[:] != 0) {
+ if (array[0:5:1] != 0) {
+ if (argc) {
+ if (array[:] == 19383)
+#if HAVE_IO
+ std::cout << " 5" << std::endl;
+#else
+ x = 5;
+#endif
+ else
+#if HAVE_IO
+ std::cout << "10" << std::endl;
+#else
+ x = 10;
+#endif
+
+ }
+ }
+ }
+ }
+ }
+ return x;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/if_test2.cc
b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/if_test2.cc
new file mode 100644
index 0000000..123b548
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/if_test2.cc
@@ -0,0 +1,26 @@
+
+int main(int argc, char **argv)
+{
+ int array[10], x;
+#if 1
+ for (int ii = 0; ii < 10; ii++)
+ array[ii] = 0;
+
+ array[:] = 19383;
+#endif
+ if (array[4] != 0) {
+ if (array[2] != 0) {
+ if (array[:] != 0) {
+ if (array[2] == 19383)
+ {
+ if (argc)
+ x = 5;
+ else
+ x = 10;
+ }
+ }
+ }
+ }
+
+ return x;
+}
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/switch_test.cc
b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/switch_test.cc
new file mode 100644
index 0000000..8cecef7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/switch_test.cc
@@ -0,0 +1,248 @@
+#if HAVE_IO
+#include <iostream>
+#endif
+#include <cstdlib>
+int main (int argc, char **argv)
+{
+ int x = 3, y, z, array[10], array2[10], TwodArray[10][10], jj,kk,ll ;
+ int FourDArray[10][10][10][10];
+ int ii = 0;
+
+ if (argc != 3)
+ {
+#if HAVE_IO
+ std::cerr << "Usage: a.out 10 15" << std::endl;
+ return 0;
+#endif
+ }
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ array[ii] = argc%3;
+ array2[ii]= 10;
+ }
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array[ii] << " ";
+ std::cout << std::endl;
+#endif
+#if 1
+ switch (array[:])
+ {
+ case 10:
+ array2[:] = 0;
+ break;
+ case 9:
+ array2[:] = 1;
+ break;
+ case 0:
+ array2[:] = 5;
+ break;
+ case 1:
+ array2[:] = 2;
+ break;
+ default:
+ array2[:] = 6;
+ }
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+#endif
+
+#if 1
+ /* this tests for nested if statements */
+ if (!(array[0:10:1] + array[0:10:1]))
+ if ((array[0:10:1] + atoi(argv[1])))
+ array2[:] = 5;
+ else
+ array2[:] = 7;
+ else
+ array2[:] = 10;
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+
+ x = atoi (argv[1])-10;
+ y = atoi (argv[1])/2;
+ z = (atoi (argv[1]))/5;
+
+ for (ii = 0; ii < 10; ii++)
+ {
+ if (ii % 2)
+ array[ii] = 0;
+ else
+ array[ii] = 1;
+ }
+
+#endif
+
+ /*printf("x = %2d y = %2d z = %2d\n", x, y, z); */
+#if 1
+ for (ii = 0; ii < 10; ii++)
+ array[ii] = 10;
+
+ /* This if loop will change all the 10's to 5's */
+ switch (array[x:y:z])
+ {
+ case 9:
+ array2[:] = 10;
+ break;
+ default:
+ array2[:] = 5;
+ break;
+ }
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+#endif
+
+#if 1
+ for (ii = 0; ii < 10; ii++)
+ array[ii] = 10;
+
+ /* This if loop will change all the 10's to 5's */
+ switch (array[atoi(argv[1])-10:atoi(argv[1]):atoi(argv[1])/15])
+ {
+ case 10:
+ array2[:] = 5;
+ break;
+ default:
+ array2[:] = 10;
+ break;
+ }
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+#endif
+
+#if 1
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ TwodArray[ii][jj] = atoi(argv[1]);
+
+
+ for (ii = 0; ii < 10; ii++)
+ array2[ii] = 10;
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ switch (TwodArray[:][:])
+ {
+ case 10:
+ array2[:] = 5;
+ break;
+ default:
+ array2[:] = 5 + array2[:];
+ break;
+ }
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+#endif
+
+#if 1
+ for (ii = 0; ii < 10; ii++)
+ array2[ii] = 10;
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ FourDArray[ii][jj][kk][ll] = atoi(argv[1]);
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ switch (FourDArray[:][:][:][:])
+ {
+ case 10:
+ array2[:] = 5;
+ break;
+ default:
+ array2[:] = 10;
+ break;
+ }
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+#endif
+
+#if 1
+ for (ii = 0; ii < 10; ii++)
+ array2[ii] = 10;
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ FourDArray[ii][jj][kk][ll] = atoi(argv[1]);
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ switch (FourDArray[0:10:1][0:5:2][9:10:-1][x:y:z]) {
+ case 5:
+ array2[:] = 10;
+ break;
+ case 10:
+ array2[:] = 5;
+ break;
+ default:
+ array2[:] = 9;
+ break;
+ }
+
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+#endif
+
+#if 1
+ for (ii = 0; ii < 10; ii++)
+ array2[ii] = 10;
+
+ for (ii = 0; ii < 10; ii++)
+ for (jj = 0; jj < 10; jj++)
+ for (kk = 0; kk < 10; kk++)
+ for (ll = 0; ll < 10; ll++)
+ FourDArray[ii][jj][kk][ll] = atoi(argv[1]);
+
+ /* atoi(argv[1]) == 10, so it will convert all 10's to 5's */
+ switch(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]) {
+ case 10:
+ array2[:] = 10;
+ break;
+ case 15:
+ array2[:] = 132;
+ break;
+ case 20:
+ array2[:] = 5;
+ break;
+ default:
+ array2[:] = 2;
+ break;
+ }
+#if HAVE_IO
+ for (ii = 0; ii < 10; ii++)
+ std::cout << array2[ii] << " " ;
+ std::cout << std::endl;
+#endif
+#endif
+
+ return 0;
+}