aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalaji V. Iyer <balaji.v.iyer@intel.com>2012-12-16 21:26:51 +0000
committerBalaji V. Iyer <balaji.v.iyer@intel.com>2012-12-16 21:26:51 +0000
commit9ec1b3bba24d69dd56beaeee2416099e36c314cc (patch)
treee84baddbdcd3e30eb19e1c7a4bf76e203c5d4ce0
parent1125812c02bef51600ff0ca7c7d15284aa1acbe9 (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.cilkplus8
-rw-r--r--gcc/c-family/ChangeLog.cilkplus11
-rw-r--r--gcc/c-family/c-cilk.c97
-rw-r--r--gcc/c/c-parser.c22
-rw-r--r--gcc/c/c-typeck.c18
-rw-r--r--gcc/testsuite/ChangeLog.cilkplus9
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp2.c16
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_invalid_cmp3.c16
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/cilk_keywords_test/errors/cilk_for_multiple_init.c21
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;
+ }
+}