aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/cp-cilkplus.c
diff options
context:
space:
mode:
authorRyan Burn <contact@rnburn.com>2016-04-27 20:41:52 +0000
committerJeff Law <law@gcc.gnu.org>2016-04-27 14:41:52 -0600
commit6bc2bb1821cc65ff6e463cb1fc930c5d152fe04d (patch)
tree01aff7302afade8fb5843d89091bb1813cde6002 /gcc/cp/cp-cilkplus.c
parent85a7c9263c2554811e9fc0e1ce7bec3b3bf6b7f5 (diff)
downloadgcc-6bc2bb1821cc65ff6e463cb1fc930c5d152fe04d.zip
gcc-6bc2bb1821cc65ff6e463cb1fc930c5d152fe04d.tar.gz
gcc-6bc2bb1821cc65ff6e463cb1fc930c5d152fe04d.tar.bz2
re PR c++/69024 ([cilkpus] cilk_spawn is broken for initializations with implicit conversion operators defined)
PR c++/69024 PR c++/68997 * cilk.c (cilk_ignorable_spawn_rhs_op): Change to external linkage. (cilk_recognize_spawn): Renamed from recognize_spawn and change to external linkage. (cilk_detect_and_unwrap): Corresponding changes. (extract_free_variables): Don't extract free variables from AGGR_INIT_EXPR slot. * c-common.h (cilk_ignorable_spawn_rhs_op): Prototype. (cilk_recognize_spawn): Likewise. PR c++/69024 PR c++/68997 * cp-gimplify.c (cp_gimplify_expr): Call cilk_cp_detect_spawn_and_unwrap instead of cilk_detect_spawn_and_unwrap. * cp-cilkplus.c (is_conversion_operator_function_decl_p): New. (find_spawn): New. (cilk_cp_detect_spawn_and_unwrap): New. * lambda.c: Include cp-cilkplus.h. * parser.c: Include cp-cilkplus.h. * cp-tree.h (cpp_validate_cilk_plus_loop): Move prototype into... * cp-cilkpus.h: New file. PR c++/69024 PR c++/68997 * g++.dg/cilk-plus/CK/pr68001.cc: Fix to not depend on broken diagnostic. * g++.dg/cilk-plus/CK/pr69024.cc: New test. * g++.dg/cilk-plus/CK/pr68997.cc: New test. Co-Authored-By: Jeff Law <law@redhat.com> From-SVN: r235534
Diffstat (limited to 'gcc/cp/cp-cilkplus.c')
-rw-r--r--gcc/cp/cp-cilkplus.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/gcc/cp/cp-cilkplus.c b/gcc/cp/cp-cilkplus.c
index 3b6cda2..7cde099 100644
--- a/gcc/cp/cp-cilkplus.c
+++ b/gcc/cp/cp-cilkplus.c
@@ -26,6 +26,110 @@
#include "cp-tree.h"
#include "tree-iterator.h"
#include "cilk.h"
+#include "c-family/c-common.h"
+
+/* Return TRUE if T is a FUNCTION_DECL for a type-conversion operator. */
+
+static bool
+is_conversion_operator_function_decl_p (tree t)
+{
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ return false;
+
+ return DECL_NAME (t) && IDENTIFIER_TYPENAME_P (DECL_NAME (t));
+}
+
+/* Recursively traverse EXP to search for a CILK_SPAWN_STMT subtree.
+ Return the CILK_SPAWN_STMT subtree if found; otherwise, the last subtree
+ searched. */
+
+static tree
+find_spawn (tree exp)
+{
+ /* Happens with C++ TARGET_EXPR. */
+ if (exp == NULL_TREE)
+ return exp;
+
+ if (cilk_ignorable_spawn_rhs_op (exp))
+ return find_spawn (TREE_OPERAND (exp, 0));
+
+ switch (TREE_CODE (exp))
+ {
+ case AGGR_INIT_EXPR:
+ {
+ /* Check for initialization via a constructor call that represents
+ implicit conversion. */
+ if (AGGR_INIT_VIA_CTOR_P (exp) && aggr_init_expr_nargs (exp) == 2)
+ return find_spawn (AGGR_INIT_EXPR_ARG (exp, 1));
+
+ /* Check for initialization via a call to a type-conversion
+ operator. */
+ tree fn = AGGR_INIT_EXPR_FN (exp);
+ if (TREE_CODE (fn) == ADDR_EXPR
+ && is_conversion_operator_function_decl_p (TREE_OPERAND (fn, 0))
+ && aggr_init_expr_nargs (exp) == 1)
+ return find_spawn (AGGR_INIT_EXPR_ARG (exp, 0));
+ }
+ break;
+
+ case CALL_EXPR:
+ {
+ /* Check for a call to a type-conversion operator. */
+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+ if (is_conversion_operator_function_decl_p (fndecl)
+ && call_expr_nargs (exp) == 1)
+ return find_spawn (CALL_EXPR_ARG (exp, 0));
+ }
+ break;
+
+ case TARGET_EXPR:
+ return find_spawn (TARGET_EXPR_INITIAL (exp));
+
+ case CLEANUP_POINT_EXPR:
+ case COMPOUND_EXPR:
+ case EXPR_STMT:
+ return find_spawn (TREE_OPERAND (exp, 0));
+
+ default:
+ break;
+ }
+
+ return exp;
+}
+
+/* Return true if *EXP0 is a recognized form of spawn. Recognized forms
+ are, after conversion to void, a call expression at outer level or an
+ assignment at outer level with the right hand side being a spawned call.
+ In addition to this, it also unwraps the CILK_SPAWN_STMT cover from the
+ CALL_EXPR that is being spawned.
+
+ Note that `=' in C++ may turn into a CALL_EXPR rather than a
+ MODIFY_EXPR. */
+
+bool
+cilk_cp_detect_spawn_and_unwrap (tree *exp0)
+{
+ tree exp = *exp0;
+
+ if (!TREE_SIDE_EFFECTS (exp))
+ return false;
+
+ /* Strip off any conversion to void. It does not affect whether spawn
+ is supported here. */
+ if (TREE_CODE (exp) == CONVERT_EXPR && VOID_TYPE_P (TREE_TYPE (exp)))
+ exp = TREE_OPERAND (exp, 0);
+
+ if (TREE_CODE (exp) == MODIFY_EXPR || TREE_CODE (exp) == INIT_EXPR)
+ exp = TREE_OPERAND (exp, 1);
+
+ exp = find_spawn (exp);
+ if (exp == NULL_TREE)
+ return false;
+
+ /* Now we should have a CALL_EXPR with a CILK_SPAWN_STMT wrapper around
+ it, or return false. */
+ return cilk_recognize_spawn (exp, exp0);
+}
/* Callback for cp_walk_tree to validate the body of a pragma simd loop
or _cilk_for loop.