From f22f434020d20d8d12bf5171cbb7ba720808ac15 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 12 May 2010 14:11:00 +0200
Subject: [PATCH] re PR middle-end/44085 (OpenMP - untied task accesses
 threadprivate - non-conforming but no msg)

	PR middle-end/44085
	* gimplify.c (enum omp_region_type): Add ORT_UNTIED_TASK,
	change value of ORT_TASK.
	(new_omp_context): Handle ORT_UNTIED_TASK like ORT_TASK.
	(omp_notice_threadprivate_variable): New function.
	(omp_notice_variable): Call it for threadprivate variables.
	If enclosing ctx is a task, print enclosing task rather than
	enclosing parallel.  Handle ORT_UNTIED_TASK like ORT_TASK.
	(gimplify_omp_task): Pass ORT_UNTIED_TASK instead of ORT_TASK
	if task has untied clause.

	* gcc.dg/gomp/pr44085.c: New test.
	* gfortran.dg/gomp/pr44085.f90: New test.

From-SVN: r159316
---
 gcc/ChangeLog                              | 11 +++++
 gcc/gimplify.c                             | 48 ++++++++++++++++++----
 gcc/testsuite/ChangeLog                    |  6 +++
 gcc/testsuite/gcc.dg/gomp/pr44085.c        | 27 ++++++++++++
 gcc/testsuite/gfortran.dg/gomp/pr44085.f90 | 25 +++++++++++
 5 files changed, 109 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/gomp/pr44085.c
 create mode 100644 gcc/testsuite/gfortran.dg/gomp/pr44085.f90

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fb4d61628fd3..52f831909f44 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
 2010-05-12  Jakub Jelinek  <jakub@redhat.com>
 
+	PR middle-end/44085
+	* gimplify.c (enum omp_region_type): Add ORT_UNTIED_TASK,
+	change value of ORT_TASK.
+	(new_omp_context): Handle ORT_UNTIED_TASK like ORT_TASK.
+	(omp_notice_threadprivate_variable): New function.
+	(omp_notice_variable): Call it for threadprivate variables.
+	If enclosing ctx is a task, print enclosing task rather than
+	enclosing parallel.  Handle ORT_UNTIED_TASK like ORT_TASK.
+	(gimplify_omp_task): Pass ORT_UNTIED_TASK instead of ORT_TASK
+	if task has untied clause.
+
 	PR debug/42278
 	* dwarf2out.c (base_type_die): Don't add name attribute here.
 	(modified_type_die): Instead of sizetype use
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index f6266e10cbc9..c74189194bd4 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -74,9 +74,10 @@ enum gimplify_omp_var_data
 enum omp_region_type
 {
   ORT_WORKSHARE = 0,
-  ORT_TASK = 1,
   ORT_PARALLEL = 2,
-  ORT_COMBINED_PARALLEL = 3
+  ORT_COMBINED_PARALLEL = 3,
+  ORT_TASK = 4,
+  ORT_UNTIED_TASK = 5
 };
 
 struct gimplify_omp_ctx
@@ -318,7 +319,7 @@ new_omp_context (enum omp_region_type region_type)
   c->privatized_types = pointer_set_create ();
   c->location = input_location;
   c->region_type = region_type;
-  if (region_type != ORT_TASK)
+  if ((region_type & ORT_TASK) == 0)
     c->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
   else
     c->default_kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
@@ -5470,6 +5471,31 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
   splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
 }
 
+/* Notice a threadprivate variable DECL used in OpenMP context CTX.
+   This just prints out diagnostics about threadprivate variable uses
+   in untied tasks.  If DECL2 is non-NULL, prevent this warning
+   on that variable.  */
+
+static bool
+omp_notice_threadprivate_variable (struct gimplify_omp_ctx *ctx, tree decl,
+				   tree decl2)
+{
+  splay_tree_node n;
+
+  if (ctx->region_type != ORT_UNTIED_TASK)
+    return false;
+  n = splay_tree_lookup (ctx->variables, (splay_tree_key)decl);
+  if (n == NULL)
+    {
+      error ("threadprivate variable %qE used in untied task", DECL_NAME (decl));
+      error_at (ctx->location, "enclosing task");
+      splay_tree_insert (ctx->variables, (splay_tree_key)decl, 0);
+    }
+  if (decl2)
+    splay_tree_insert (ctx->variables, (splay_tree_key)decl2, 0);
+  return false;
+}
+
 /* Record the fact that DECL was used within the OpenMP context CTX.
    IN_CODE is true when real code uses DECL, and false when we should
    merely emit default(none) errors.  Return true if DECL is going to
@@ -5490,14 +5516,14 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
   if (is_global_var (decl))
     {
       if (DECL_THREAD_LOCAL_P (decl))
-	return false;
+	return omp_notice_threadprivate_variable (ctx, decl, NULL_TREE);
 
       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))
-	    return false;
+	    return omp_notice_threadprivate_variable (ctx, decl, value);
 	}
     }
 
@@ -5523,7 +5549,10 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
 	case OMP_CLAUSE_DEFAULT_NONE:
 	  error ("%qE not specified in enclosing parallel",
 		 DECL_NAME (decl));
-	  error_at (ctx->location, "enclosing parallel");
+	  if ((ctx->region_type & ORT_TASK) != 0)
+	    error_at (ctx->location, "enclosing task");
+	  else
+	    error_at (ctx->location, "enclosing parallel");
 	  /* FALLTHRU */
 	case OMP_CLAUSE_DEFAULT_SHARED:
 	  flags |= GOVD_SHARED;
@@ -5536,7 +5565,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
 	  break;
 	case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
 	  /* decl will be either GOVD_FIRSTPRIVATE or GOVD_SHARED.  */
-	  gcc_assert (ctx->region_type == ORT_TASK);
+	  gcc_assert ((ctx->region_type & ORT_TASK) != 0);
 	  if (ctx->outer_context)
 	    omp_notice_variable (ctx->outer_context, decl, in_code);
 	  for (octx = ctx->outer_context; octx; octx = octx->outer_context)
@@ -6039,7 +6068,10 @@ gimplify_omp_task (tree *expr_p, gimple_seq *pre_p)
   gimple_seq body = NULL;
   struct gimplify_ctx gctx;
 
-  gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p, ORT_TASK);
+  gimplify_scan_omp_clauses (&OMP_TASK_CLAUSES (expr), pre_p,
+			     find_omp_clause (OMP_TASK_CLAUSES (expr),
+					      OMP_CLAUSE_UNTIED)
+			     ? ORT_UNTIED_TASK : ORT_TASK);
 
   push_gimplify_context (&gctx);
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d8ea55ea61f0..d2628e4b4220 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-05-12  Jakub Jelinek  <jakub@redhat.com>
+
+	PR middle-end/44085
+	* gcc.dg/gomp/pr44085.c: New test.
+	* gfortran.dg/gomp/pr44085.f90: New test.
+
 2010-05-12  Iain Sandoe  <iains@gcc.gnu.org>
 
 	* objc-obj-c++-shared/Object1.m: New.
diff --git a/gcc/testsuite/gcc.dg/gomp/pr44085.c b/gcc/testsuite/gcc.dg/gomp/pr44085.c
new file mode 100644
index 000000000000..55462abe504e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr44085.c
@@ -0,0 +1,27 @@
+/* PR middle-end/44085 */
+/* { dg-do compile } */
+/* { dg-require-effective-target tls_native } */
+/* { dg-options "-fopenmp" } */
+
+int thr1, thr2;
+#pragma omp threadprivate (thr1, thr2)
+
+void
+foo (void)
+{
+#pragma omp task untied	/* { dg-error "enclosing task" } */
+  {
+    thr1++;		/* { dg-error "used in untied task" } */
+    thr2 |= 4;		/* { dg-error "used in untied task" } */
+  }
+}
+
+void
+bar (void)
+{
+#pragma omp task
+  {
+    thr1++;
+    thr2 |= 4;
+  }
+}
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr44085.f90 b/gcc/testsuite/gfortran.dg/gomp/pr44085.f90
new file mode 100644
index 000000000000..db8fbbc9544f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr44085.f90
@@ -0,0 +1,25 @@
+! PR middle-end/44085
+! { dg-do compile }
+! { dg-require-effective-target tls_native }
+! { dg-options "-fopenmp" }
+
+  integer, save :: thr1, thr2
+  integer :: thr3, thr4
+  common /thrs/ thr3, thr4
+!$omp threadprivate (thr1, thr2, /thrs/)
+
+!$omp task untied		! { dg-error "enclosing task" }
+  thr1 = thr1 + 1		! { dg-error "used in untied task" }
+  thr2 = thr2 + 2		! { dg-error "used in untied task" }
+  thr3 = thr3 + 3		! { dg-error "used in untied task" }
+  thr4 = thr4 + 4		! { dg-error "used in untied task" }
+!$omp end task
+
+!$omp task
+  thr1 = thr1 + 1
+  thr2 = thr2 + 2
+  thr3 = thr3 + 3
+  thr4 = thr4 + 4
+!$omp end task
+
+  end
-- 
GitLab