From 25c229379aa6c0bc8cadd913e014dd9be62453f3 Mon Sep 17 00:00:00 2001 From: "Balaji V. Iyer" Date: Mon, 3 Jun 2013 22:28:09 +0000 Subject: [PATCH] Fixed a bug in expansion of array notations in if-statement conditions. 2013-06-03 Balaji V. Iyer * 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 * 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 | 13 +++++ gcc/c/c-array-notation.c | 20 ++++++-- gcc/c/c-parser.c | 19 ++------ gcc/c/c-typeck.c | 28 +++++++++++ gcc/testsuite/ChangeLog | 6 +++ .../c-c++-common/cilk-plus/AN/if_test_errors.c | 56 ++++++++++++++++++++++ .../c-c++-common/cilk-plus/AN/rank_mismatch.c | 7 ++- 7 files changed, 129 insertions(+), 20 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 437be91..48be2fd 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,5 +1,18 @@ 2013-06-03 Balaji V. Iyer + * 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 + 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 diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c index 0807466..bcd0922 100644 --- a/gcc/c/c-array-notation.c +++ b/gcc/c/c-array-notation.c @@ -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; diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index b89d8c1..d6a500e 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -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 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 749c8e2..e5e1455 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -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) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a1f0827..e0f75fd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-06-03 Balaji V. Iyer + + * 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 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 index 0000000..d17d8cf --- /dev/null +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/if_test_errors.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ + +#include +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; +} diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c index a8c9dab..b5e37ce 100644 --- a/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c +++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/rank_mismatch.c @@ -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]; -- 2.7.4