diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-12 08:52:06 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-12-12 08:52:06 +0000 |
commit | b45e536ef744c5935d828d6d2369ead30b00d31e (patch) | |
tree | 5b5f9bb96f851af0b0a2ebcbf289d3324fd65c0a /gcc/gimplify.c | |
parent | c76a3c2a0dc4cfa17ef7fc66bb8a5221d5b375b6 (diff) | |
download | gcc-b45e536ef744c5935d828d6d2369ead30b00d31e.tar.gz |
PR libgomp/59467
* gimplify.c (omp_check_private): Add copyprivate argument, if it
is true, don't check omp_privatize_by_reference.
(gimplify_scan_omp_clauses): For OMP_CLAUSE_COPYPRIVATE verify
decl is private in outer context. Adjust omp_check_private caller.
* gfortran.dg/gomp/pr59467.f90: New test.
* c-c++-common/gomp/pr59467.c: New test.
* testsuite/libgomp.fortran/crayptr2.f90: Add private (d) clause to
!$omp parallel.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205922 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimplify.c')
-rw-r--r-- | gcc/gimplify.c | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 8bcce22a938..1ca847ac759 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -5817,7 +5817,7 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, bool simd) region's REDUCTION clause. */ static bool -omp_check_private (struct gimplify_omp_ctx *ctx, tree decl) +omp_check_private (struct gimplify_omp_ctx *ctx, tree decl, bool copyprivate) { splay_tree_node n; @@ -5826,8 +5826,11 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl) ctx = ctx->outer_context; if (ctx == NULL) return !(is_global_var (decl) - /* References might be private, but might be shared too. */ - || lang_hooks.decls.omp_privatize_by_reference (decl)); + /* References might be private, but might be shared too, + when checking for copyprivate, assume they might be + private, otherwise assume they might be shared. */ + || (!copyprivate + && lang_hooks.decls.omp_privatize_by_reference (decl))); if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0) continue; @@ -6037,12 +6040,36 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p, remove = true; break; } + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_COPYPRIVATE + && !remove + && !omp_check_private (ctx, decl, true)) + { + remove = true; + if (is_global_var (decl)) + { + if (DECL_THREAD_LOCAL_P (decl)) + remove = false; + else if (DECL_HAS_VALUE_EXPR_P (decl)) + { + tree value = get_base_address (DECL_VALUE_EXPR (decl)); + + if (value + && DECL_P (value) + && DECL_THREAD_LOCAL_P (value)) + remove = false; + } + } + if (remove) + error_at (OMP_CLAUSE_LOCATION (c), + "copyprivate variable %qE is not threadprivate" + " or private in outer context", DECL_NAME (decl)); + } do_notice: if (outer_ctx) omp_notice_variable (outer_ctx, decl, true); if (check_non_private && region_type == ORT_WORKSHARE - && omp_check_private (ctx, decl)) + && omp_check_private (ctx, decl, false)) { error ("%s variable %qE is private in outer context", check_non_private, DECL_NAME (decl)); |