From 3bfdc94f566983f2cc40dca1fca9925a8175f0da Mon Sep 17 00:00:00 2001 From: mpolacek Date: Thu, 6 Mar 2014 13:41:46 +0000 Subject: [PATCH] PR c/60197 c-family/ * cilk.c (contains_cilk_spawn_stmt): New function. (contains_cilk_spawn_stmt_walker): Likewise. (recognize_spawn): Give error on invalid use of _Cilk_spawn. * c-common.h (contains_cilk_spawn_stmt): Add declaration. c/ * c-typeck.c (c_finish_return): Call contains_cilk_spawn_stmt instead of checking tree code. cp/ * typeck.c (check_return_expr): Call contains_cilk_spawn_stmt instead of checking tree code. testsuite/ * c-c++-common/cilk-plus/CK/pr60197.c: New test. * c-c++-common/cilk-plus/CK/pr60197-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208382 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/c-family/ChangeLog | 8 +++ gcc/c-family/c-common.h | 1 + gcc/c-family/cilk.c | 25 ++++++++ gcc/c/ChangeLog | 6 ++ gcc/c/c-typeck.c | 2 +- gcc/cp/ChangeLog | 6 ++ gcc/cp/typeck.c | 2 +- gcc/testsuite/ChangeLog | 6 ++ .../c-c++-common/cilk-plus/CK/pr60197-2.c | 35 ++++++++++++ gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197.c | 66 ++++++++++++++++++++++ 10 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197-2.c create mode 100644 gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index a775d4c..0c22f89 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2014-03-06 Marek Polacek + + PR c/60197 + * cilk.c (contains_cilk_spawn_stmt): New function. + (contains_cilk_spawn_stmt_walker): Likewise. + (recognize_spawn): Give error on invalid use of _Cilk_spawn. + * c-common.h (contains_cilk_spawn_stmt): Add declaration. + 2014-03-03 Jakub Jelinek * c-pragma.c (c_pp_lookup_pragma): Handle PRAGMA_CILK_SIMD. diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index f074ab1..1099b10 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1389,4 +1389,5 @@ extern tree make_cilk_frame (tree); extern tree create_cilk_function_exit (tree, bool, bool); extern tree cilk_install_body_pedigree_operations (tree); extern void cilk_outline (tree, tree *, void *); +extern bool contains_cilk_spawn_stmt (tree); #endif /* ! GCC_C_COMMON_H */ diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c index f2179dfc..6a7bf4f 100644 --- a/gcc/c-family/cilk.c +++ b/gcc/c-family/cilk.c @@ -235,6 +235,9 @@ recognize_spawn (tree exp, tree *exp0) walk_tree (exp0, unwrap_cilk_spawn_stmt, NULL, NULL); spawn_found = true; } + /* _Cilk_spawn can't be wrapped in expression such as PLUS_EXPR. */ + else if (contains_cilk_spawn_stmt (exp)) + error ("invalid use of %<_Cilk_spawn%>"); return spawn_found; } @@ -1292,3 +1295,25 @@ build_cilk_sync (void) TREE_SIDE_EFFECTS (sync) = 1; return sync; } + +/* Helper for contains_cilk_spawn_stmt, callback for walk_tree. Return + non-null tree if TP contains CILK_SPAWN_STMT. */ + +static tree +contains_cilk_spawn_stmt_walker (tree *tp, int *, void *) +{ + if (TREE_CODE (*tp) == CILK_SPAWN_STMT) + return *tp; + else + return NULL_TREE; +} + +/* Returns true if EXPR or any of its subtrees contain CILK_SPAWN_STMT + node. */ + +bool +contains_cilk_spawn_stmt (tree expr) +{ + return walk_tree (&expr, contains_cilk_spawn_stmt_walker, NULL, NULL) + != NULL_TREE; +} diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 5e482a3..e9d25d5 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2014-03-06 Marek Polacek + + PR c/60197 + * c-typeck.c (c_finish_return): Call contains_cilk_spawn_stmt instead + of checking tree code. + 2014-02-19 Prathamesh Kulkarni * c-parser.c (c_parser_declspecs): Replace call to error by error_at. diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 2b54290..7c4ba0e 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -9140,7 +9140,7 @@ c_finish_return (location_t loc, tree retval, tree origtype) return error_mark_node; } } - if (flag_cilkplus && retval && TREE_CODE (retval) == CILK_SPAWN_STMT) + if (flag_cilkplus && retval && contains_cilk_spawn_stmt (retval)) { error_at (loc, "use of %<_Cilk_spawn%> in a return statement is not " "allowed"); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 70db35c..4aa9c2b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-03-06 Marek Polacek + + PR c/60197 + * typeck.c (check_return_expr): Call contains_cilk_spawn_stmt instead + of checking tree code. + 2014-03-06 Paolo Carlini * parser.c (cp_lexer_set_source_position): New. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 29f9e9d..ae2e503 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -8332,7 +8332,7 @@ check_return_expr (tree retval, bool *no_warning) *no_warning = false; - if (flag_cilkplus && retval && TREE_CODE (retval) == CILK_SPAWN_STMT) + if (flag_cilkplus && retval && contains_cilk_spawn_stmt (retval)) { error_at (EXPR_LOCATION (retval), "use of %<_Cilk_spawn%> in a return " "statement is not allowed"); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d9e6105..779fa96 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-03-06 Marek Polacek + + PR c/60197 + * c-c++-common/cilk-plus/CK/pr60197.c: New test. + * c-c++-common/cilk-plus/CK/pr60197-2.c: New test. + 2014-03-06 Jakub Jelinek PR target/58595 diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197-2.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197-2.c new file mode 100644 index 0000000..1e5ca00 --- /dev/null +++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197-2.c @@ -0,0 +1,35 @@ +/* PR c/60197 */ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ + +extern int foo (void); + +int +fn1 (void) +{ + int i; + i = (_Cilk_spawn foo ()) + 1; /* { dg-error "invalid use of" } */ + return i; +} + +int +fn2 (void) +{ + int i = (_Cilk_spawn foo ()) + 1; /* { dg-error "invalid use of" } */ + return i; +} + +int +fn3 (int j, int k, int l) +{ + int i = (((((_Cilk_spawn foo ()) + 1) - l) * k) / j); /* { dg-error "invalid use of" } */ + return i; +} + +int +fn4 (int j, int k, int l) +{ + int i; + i = (((((_Cilk_spawn foo ()) + 1) - l) * k) / j); /* { dg-error "invalid use of" } */ + return i; +} diff --git a/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197.c b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197.c new file mode 100644 index 0000000..2b47d1e --- /dev/null +++ b/gcc/testsuite/c-c++-common/cilk-plus/CK/pr60197.c @@ -0,0 +1,66 @@ +/* PR c/60197 */ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ + +extern int foo (void); +extern int bar (int); + +int +fn1 (void) +{ + return (_Cilk_spawn foo ()) * 2; /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn2 (void) +{ + return (_Cilk_spawn foo ()) > 2; /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn3 (int i, int j, int k) +{ + return ((((((_Cilk_spawn foo () + i) - j) * k) / j) | i) ^ k) ; /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn4 (int i, int j, int k) +{ + return (((((i - _Cilk_spawn foo ()) * k) / j) | i) ^ k); /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn5 (void) +{ + return _Cilk_spawn foo (); /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn6 (void) +{ + return _Cilk_spawn foo () + _Cilk_spawn foo (); /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn7 (void) +{ + return 5 % _Cilk_spawn foo (); /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn8 (void) +{ + return !_Cilk_spawn foo (); /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn9 (void) +{ + return foo () && _Cilk_spawn foo (); /* { dg-error "in a return statement is not allowed" } */ +} + +int +fn10 (void) +{ + return bar (_Cilk_spawn foo ()); /* { dg-error "in a return statement is not allowed" } */ +} -- 2.7.4