Hi! This patch attempts to enhance error diagnostic in case of CilkPlus and fixes PR68001.
Bootstrapped and regtested for x86_64. Is it ok for trunk? Thanks, Igor ChangeLog: c-family 2015-11-02 Igor Zamyatin <igor.zamya...@intel.com> PR c++/68001 * c-gimplify.c (c_gimplify_expr): Stop the process if see an error. * cilk.c (recognize_spawn): Determine location in a more precise way. cp 2015-11-02 Igor Zamyatin <igor.zamya...@intel.com> PR c++/68001 * cp-gimplify.c (cp_gimplify_expr): Stop the process if see an error. testsuite 2015-11-02 Igor Zamyatin <igor.zamya...@intel.com> PR c++/68001 * g++.dg/cilk-plus/CK/pr68001.cc: New test. diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c index 92987b5..5b173d5 100644 --- a/gcc/c-family/c-gimplify.c +++ b/gcc/c-family/c-gimplify.c @@ -283,15 +283,16 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, case CILK_SPAWN_STMT: gcc_assert - (fn_contains_cilk_spawn_p (cfun) - && cilk_detect_spawn_and_unwrap (expr_p)); + (fn_contains_cilk_spawn_p (cfun) + && cilk_detect_spawn_and_unwrap (expr_p)); - /* If errors are seen, then just process it as a CALL_EXPR. */ if (!seen_error ()) { cilk_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p); return (enum gimplify_status) gimplify_cilk_spawn (expr_p); } + return GS_ERROR; + case MODIFY_EXPR: case INIT_EXPR: case CALL_EXPR: diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c index 1c316a4..77cb6e4 100644 --- a/gcc/c-family/cilk.c +++ b/gcc/c-family/cilk.c @@ -82,6 +82,8 @@ struct wrapper_data tree block; }; +static tree +contains_cilk_spawn_stmt_walker (tree *tp, int *, void *); static void extract_free_variables (tree, struct wrapper_data *, enum add_variable_type); static HOST_WIDE_INT cilk_wrapper_count; @@ -241,7 +243,19 @@ recognize_spawn (tree exp, tree *exp0) } /* _Cilk_spawn can't be wrapped in expression such as PLUS_EXPR. */ else if (contains_cilk_spawn_stmt (exp)) - error_at (EXPR_LOCATION (exp), "invalid use of %<_Cilk_spawn%>"); + { + location_t loc = EXPR_LOCATION (exp); + if (loc == UNKNOWN_LOCATION) + { + tree stmt = walk_tree (&exp, + contains_cilk_spawn_stmt_walker, + NULL, + NULL); + gcc_assert (stmt != NULL_TREE); + loc = EXPR_LOCATION (stmt); + } + error_at (loc, "invalid use of %<_Cilk_spawn%>"); + } return spawn_found; } diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index e37cbc7..6b444d6 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -625,6 +625,9 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p); return (enum gimplify_status) gimplify_cilk_spawn (expr_p); } + else if (seen_error ()) + return GS_ERROR; + cp_gimplify_init_expr (expr_p); if (TREE_CODE (*expr_p) != INIT_EXPR) return GS_OK; @@ -733,16 +736,17 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) break; case CILK_SPAWN_STMT: - gcc_assert - (fn_contains_cilk_spawn_p (cfun) - && cilk_detect_spawn_and_unwrap (expr_p)); + gcc_assert + (fn_contains_cilk_spawn_p (cfun) + && cilk_detect_spawn_and_unwrap (expr_p)); - /* If errors are seen, then just process it as a CALL_EXPR. */ if (!seen_error ()) { cilk_cp_gimplify_call_params_in_spawned_fn (expr_p, pre_p, post_p); return (enum gimplify_status) gimplify_cilk_spawn (expr_p); } + return GS_ERROR; + case CALL_EXPR: if (fn_contains_cilk_spawn_p (cfun) && cilk_detect_spawn_and_unwrap (expr_p) diff --git a/gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc b/gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc new file mode 100644 index 0000000..6137c07 --- /dev/null +++ b/gcc/testsuite/g++.dg/cilk-plus/CK/pr68001.cc @@ -0,0 +1,19 @@ +/* PR middle-end/68001 */ +/* { dg-do compile } */ +/* { dg-options "-fcilkplus" } */ + +#include <cilk/cilk.h> +#include <vector> + +std::vector<double> f() { + std::vector<double> v; + return v; +} + +int main() +{ + std::vector<double> x = cilk_spawn f(); /* { dg-error "invalid use of" } */ + std::vector<double> y = f(); + cilk_sync; + return 0; +}