diff options
author | Balaji V. Iyer <balaji.v.iyer@intel.com> | 2012-12-16 21:26:51 +0000 |
---|---|---|
committer | Balaji V. Iyer <balaji.v.iyer@intel.com> | 2012-12-16 21:26:51 +0000 |
commit | 9ec1b3bba24d69dd56beaeee2416099e36c314cc (patch) | |
tree | e84baddbdcd3e30eb19e1c7a4bf76e203c5d4ce0 | |
parent | 1125812c02bef51600ff0ca7c7d15284aa1acbe9 (diff) |
Added some more error checking (e.g. multiple stmts in _Cilk for etc.)
gcc/c-family/ChangeLog.cilkplus
+2012-12-16 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c-cilk.c (extract_for_fields): Set invalid to false as the
+ initialization value. Replaced unreachable with a comparison error.
+ Also, added a check if the end-value is less than start value for
+ _Cilk_for.
+ (compute_loop_var): Set the convert value to unsigned long for pointer
+ type count.
+ (build_cilk_for_body): Added a check for pointer type, and if so, do
+ a type convert (this is done twice).
+
gcc/ChangeLog.cilkplus
+2012-12-16 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * c/c-typeck.c (c_finish_cilk_loop): Added a check for multiple expr. in
+ condition or increment inside a _Cilk_for. If so, then emit an error.
+ * c/c-parser.c (c_parser_cilk_for_statement): Added a check for
+ multiple expressions for initialization for a Cilk_for. If so, then
+ emit an error.
+
gcc/testsuite/ChangeLog.cilkplus
+2012-12-16 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp3.c:
+ New test.
+ * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp2.c:
+ Likewise.
+ * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_multiple_init.c:
+ Likewise.
+
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/cilkplus@194541 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.cilkplus | 8 | ||||
-rw-r--r-- | gcc/c-family/ChangeLog.cilkplus | 11 | ||||
-rw-r--r-- | gcc/c-family/c-cilk.c | 97 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 22 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog.cilkplus | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp2.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp3.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_multiple_init.c | 21 |
9 files changed, 189 insertions, 29 deletions
diff --git a/gcc/ChangeLog.cilkplus b/gcc/ChangeLog.cilkplus index 2afb0830848..f773b914fd8 100644 --- a/gcc/ChangeLog.cilkplus +++ b/gcc/ChangeLog.cilkplus @@ -1,3 +1,11 @@ +2012-12-16 Balaji V. Iyer <balaji.v.iyer@intel.com> + + * c/c-typeck.c (c_finish_cilk_loop): Added a check for multiple expr. in + condition or increment inside a _Cilk_for. If so, then emit an error. + * c/c-parser.c (c_parser_cilk_for_statement): Added a check for + multiple expressions for initialization for a Cilk_for. If so, then + emit an error. + 2012-12-14 Balaji V. Iyer <balaji.v.iyer@intel.com> * c/c-parser.c (c_parser_cilk_for_statement): Replaced unknown location with the diff --git a/gcc/c-family/ChangeLog.cilkplus b/gcc/c-family/ChangeLog.cilkplus index ab4e088a5a7..666bad0f093 100644 --- a/gcc/c-family/ChangeLog.cilkplus +++ b/gcc/c-family/ChangeLog.cilkplus @@ -1,3 +1,14 @@ +2012-12-16 Balaji V. Iyer <balaji.v.iyer@intel.com> + + * c-cilk.c (extract_for_fields): Set invalid to false as the + initialization value. Replaced unreachable with a comparison error. + Also, added a check if the end-value is less than start value for + _Cilk_for. + (compute_loop_var): Set the convert value to unsigned long for pointer + type count. + (build_cilk_for_body): Added a check for pointer type, and if so, do + a type convert (this is done twice). + 2012-12-12 Balaji V. Iyer <balaji.v.iyer@intel.com> * c-typeck.c (c_finish_cilk_loop) Added location for error reporting. diff --git a/gcc/c-family/c-cilk.c b/gcc/c-family/c-cilk.c index 8d873f9f187..f1bbaf6aff9 100644 --- a/gcc/c-family/c-cilk.c +++ b/gcc/c-family/c-cilk.c @@ -1772,7 +1772,9 @@ extract_for_fields (struct cilk_for_desc *cfd, tree loop) enum tree_code incr_op; bool inclusive, iterator, negate_incr, exactly_one; int incr_direction, cond_direction, direction; - + + cfd->invalid = false; /* Initalize it to everything is OK!. */ + switch (TREE_CODE (cond)) { case NE_EXPR: @@ -1814,7 +1816,15 @@ extract_for_fields (struct cilk_for_desc *cfd, tree loop) cond_direction = -cond_direction; } else - gcc_unreachable (); + { + /* If we got here, then the variable initialized for _Cilk_for is not + theone that is condition checked. So, we issue an error. This maybe + changed in the future. */ + error_at (EXPR_LOCATION (cond), "comparison is not done against the " + "induction variable."); + cfd->invalid = true; + return; + } gcc_assert (TREE_CODE (TREE_TYPE (limit)) != ARRAY_TYPE); @@ -1961,6 +1971,17 @@ extract_for_fields (struct cilk_for_desc *cfd, tree loop) direction = cond_direction; + if (init && limit && TREE_CONSTANT (init) && TREE_CONSTANT (limit) + && INTEGRAL_TYPE_P (TREE_TYPE (init)) + && INTEGRAL_TYPE_P (TREE_TYPE (limit)) + && tree_int_cst_lt (limit, init)) + { + error_at (EXPR_LOCATION (cond), "end-condition value is greater than " + "starting point."); + cfd->invalid = true; + return; + } + cfd->invalid = false; cfd->iterator = iterator; cfd->inclusive = inclusive; @@ -2219,6 +2240,7 @@ compute_loop_var (struct cilk_for_desc *cfd, tree loop_var, tree lower_bound) tree count_type = TREE_TYPE (loop_var); tree scaled, adjusted; int incr_sign = cfd->incr_sign; + tree cvt_val; enum tree_code add_op = incr_sign >= 0 ? PLUS_EXPR : MINUS_EXPR; /* Compute an expression to be added or subtracted. @@ -2267,9 +2289,11 @@ compute_loop_var (struct cilk_for_desc *cfd, tree loop_var, tree lower_bound) the range does not fit in a signed int. The sum of the lower bound and the count is representable. Do the addition or subtraction in the wider type, then narrow. */ - adjusted = fold_build2 (add_op, count_type, - cilk_loop_convert (count_type, lower_bound), - scaled); + if (POINTER_TYPE_P (count_type)) + cvt_val = cilk_loop_convert (long_unsigned_type_node, TREE_OPERAND (lower_bound, 0)); + else + cvt_val = cilk_loop_convert (count_type, lower_bound); + adjusted = fold_build2 (add_op, count_type, cvt_val, scaled); return build2 (MODIFY_EXPR, void_type_node, cfd->var2, cilk_loop_convert (cfd->var_type, adjusted)); @@ -2305,6 +2329,7 @@ build_cilk_for_body (struct cilk_for_desc *cfd) tree lower_bound; tree loop_var; tree tempx, tempy; + tree mod_expr = NULL_TREE; declare_cilk_for_parms (cfd); @@ -2344,9 +2369,22 @@ build_cilk_for_body (struct cilk_for_desc *cfd) loop_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE, cfd->var_type); DECL_CONTEXT (loop_var) = fndecl; - add_stmt (build_modify_expr (UNKNOWN_LOCATION, loop_var, TREE_TYPE (loop_var), - NOP_EXPR, UNKNOWN_LOCATION, - cfd->min_parm, TREE_TYPE (cfd->min_parm))); + if (POINTER_TYPE_P (TREE_TYPE (loop_var))) + { + tree new_min_parm = build1 (CONVERT_EXPR, TREE_TYPE (loop_var), + cfd->min_parm); + mod_expr = build_modify_expr (UNKNOWN_LOCATION, loop_var, + TREE_TYPE (loop_var), NOP_EXPR, + UNKNOWN_LOCATION, new_min_parm, + TREE_TYPE (new_min_parm)); + } + else + mod_expr = build_modify_expr (UNKNOWN_LOCATION, loop_var, + TREE_TYPE (loop_var), + NOP_EXPR, UNKNOWN_LOCATION, + cfd->min_parm, TREE_TYPE (cfd->min_parm)); + + add_stmt (mod_expr); /* The new loop body is @@ -2383,19 +2421,38 @@ build_cilk_for_body (struct cilk_for_desc *cfd) add_stmt (loop_body); - tempx = build2 (MODIFY_EXPR, void_type_node, loop_var, - build2 (PLUS_EXPR, TREE_TYPE (loop_var), - loop_var, - build_int_cst (TREE_TYPE (loop_var), 1))); + if (POINTER_TYPE_P (TREE_TYPE (loop_var))) + { + tree cmp_expr = NULL_TREE; + tree new_incr_type = TREE_TYPE (TREE_TYPE (loop_var)); + tree new_max_parm = build1 (CONVERT_EXPR, TREE_TYPE (loop_var), + cfd->max_parm); + tempx = build_modify_expr (EXPR_LOCATION (loop_var), loop_var, + TREE_TYPE (loop_var), PLUS_EXPR, + EXPR_LOCATION (loop_var), + build_int_cst (new_incr_type, 1), + TREE_TYPE (loop_var)); + cmp_expr = build2 (LT_EXPR, boolean_type_node, loop_var, new_max_parm); + tempy = build3 (COND_EXPR, void_type_node, cmp_expr, + build1 (GOTO_EXPR, void_type_node, lab), + build_empty_stmt (EXPR_LOCATION (loop_var))); + } + else + { + tempx = build2 (MODIFY_EXPR, void_type_node, loop_var, + build2 (PLUS_EXPR, TREE_TYPE (loop_var), + loop_var, + build_int_cst (TREE_TYPE (loop_var), 1))); + + tempy = build3 (COND_EXPR, void_type_node, + build2 (LT_EXPR, boolean_type_node, loop_var, + build_c_cast (UNKNOWN_LOCATION, + TREE_TYPE (loop_var), + cfd->max_parm)), + build1 (GOTO_EXPR, void_type_node, lab), + build_empty_stmt (UNKNOWN_LOCATION)); + } add_stmt (tempx); - - tempy = build3 (COND_EXPR, void_type_node, - build2 (LT_EXPR, boolean_type_node, loop_var, - build_c_cast (UNKNOWN_LOCATION, - TREE_TYPE (loop_var), cfd->max_parm)), - build1 (GOTO_EXPR, void_type_node, lab), - build_empty_stmt (UNKNOWN_LOCATION)); - add_stmt (tempy); pop_stmt_list (loop); diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index d8e1eb0db2e..ec5dc7c5b27 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -11876,13 +11876,21 @@ c_parser_cilk_for_statement (c_parser *parser, tree grain) { /* Take the initial value of the set. */ tree init_exp = c_parser_expression (parser).value; - - cvar = lookup_name (next_token); - /* Set the initial value of the induction var as the value - that is set to whatever the induction variable is set - here in the init expression. */ - if (TREE_CODE (init_exp) == MODIFY_EXPR) - DECL_INITIAL (cvar) = TREE_OPERAND (init_exp, 1); + if (init_exp && TREE_CODE (init_exp) == COMPOUND_EXPR) + { + error_at (loc, "cannot have multiple initializations in " + "_Cilk_for"); + cvar = error_mark_node; + } + else + { + cvar = lookup_name (next_token); + /* Set the initial value of the induction var as the value + that is set to whatever the induction variable is set + here in the init expression. */ + if (TREE_CODE (init_exp) == MODIFY_EXPR) + DECL_INITIAL (cvar) = TREE_OPERAND (init_exp, 1); + } } } c_parser_consume_token (parser); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 144f057e095..7abb1f6092b 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -11028,8 +11028,22 @@ c_finish_cilk_loop (location_t start_locus, tree cvar, } else if (TREE_CONSTANT (cvar) || TREE_READONLY (cvar)) { - error_at (start_locus, "_Cilk_for induction variable cannot be constant or " - "readonly"); + error_at (start_locus, "_Cilk_for induction variable cannot be constant " + "or readonly"); + return; + } + + if (incr && TREE_CODE (incr) == COMPOUND_EXPR) + { + error_at (start_locus, "Only single increment expression is allowed in " + "_Cilk_for"); + return; + } + + if (cond && TREE_CODE (incr) == COMPOUND_EXPR) + { + error_at (start_locus, "Only single condition expression is allowed in " + "_Cilk_for"); return; } init = DECL_INITIAL (cvar); diff --git a/gcc/testsuite/ChangeLog.cilkplus b/gcc/testsuite/ChangeLog.cilkplus index 47149962c26..c90c98f79fe 100644 --- a/gcc/testsuite/ChangeLog.cilkplus +++ b/gcc/testsuite/ChangeLog.cilkplus @@ -1,3 +1,12 @@ +2012-12-16 Balaji V. Iyer <balaji.v.iyer@intel.com> + + * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp3.c: + New test. + * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp2.c: + Likewise. + * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_multiple_init.c: + Likewise. + 2012-12-14 Balaji V. Iyer <balaji.v.iyer@intel.com> * gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_compares.c: diff --git a/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp2.c b/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp2.c new file mode 100644 index 00000000000..dc7b9257589 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp2.c @@ -0,0 +1,16 @@ +/* <feature> + Unsigned wraparound is not allowed + </feature> +*/ + +int a[50000]; + +int main(void) +{ + unsigned char i; + _Cilk_for(i = 2; i != 1; i++) /* { dg-error "end-condition value is greater than starting" } */ + { + a[i] = i; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp3.c b/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp3.c new file mode 100644 index 00000000000..5e3eb2af8fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp3.c @@ -0,0 +1,16 @@ +/* <feature> + The three items inside parentheses in the grammar, separated by semicolons, + are the initialization, condition, and increment + </feature> +*/ + +int a[5000]; + +void func () +{ + int i, j = 0; + _Cilk_for(i = 0; i < 5000 || j == 0; i++) /* { dg-error "_Cilk_for condition must be one of the" } */ + { + a[i] = i; + } +} diff --git a/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_multiple_init.c b/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_multiple_init.c new file mode 100644 index 00000000000..d9a51641ede --- /dev/null +++ b/gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_multiple_init.c @@ -0,0 +1,21 @@ +/* <feature> + The three items inside parentheses in the grammar, separated by semicolons, + are the initialization, condition, and increment + </feature> +*/ + +#define ARRAY_SIZE 50000 +int a[ARRAY_SIZE]; + +void func() +{ + int i, j, k = 0; + _Cilk_for(i = 0, j = 0; i < ARRAY_SIZE; i++) /* { dg-error "cannot have multiple initializations in" } */ + { + a[i] = i; + } + _Cilk_for(i = 0, j = 0, k = 0; i < ARRAY_SIZE; i++) /* { dg-error "cannot have multiple initializations in" } */ + { + a[i] = i; + } +} |