Thanks for the review.

On 16/01/2021 9:25 am, Jakub Jelinek wrote:
On Fri, Jan 15, 2021 at 03:07:56PM +0000, Kwok Cheung Yeung wrote:
+       {
+         tree detach_decl = OMP_CLAUSE_DECL (*detach_seen);
+
+         for (pc = &clauses, c = clauses; c ; c = *pc)
+           {
+             bool remove = false;
+             if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
+                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
+                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+                  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+                 && OMP_CLAUSE_DECL (c) == detach_decl)
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "the event handle of a %<detach%> clause "
+                           "should not be in a data-sharing clause");
+                 remove = true;
+               }

I think you don't need this loop, instead you could just check
                if (bitmap_bit_p (&generic_head, DECL_UID (detach_decl))
                    || bitmap_bit_p (&firstprivate_head, DECL_UID (detach_decl))
                    || bitmap_bit_p (&lastprivate_head, DECL_UID (detach_decl)))


I think the main problem with this is that you cannot then point to the location of the offending data-sharing clause. Given a task construct with 'detach(x) shared(x)', I would tend to think of the 'shared(x)' as being the incorrect part here, and so would want the error to point to it. Unless you have any objections, I am inclined to keep this as it is?

@@ -2416,6 +2421,64 @@ finish_taskreg_scan (omp_context *ctx)
              TYPE_FIELDS (ctx->srecord_type) = f1;
            }
        }
+      if (detach_clause)
+       {
+         tree c, field;
+
+         /* Look for a firstprivate clause with the detach event handle.  */
+         for (c = gimple_omp_taskreg_clauses (ctx->stmt);
+              c; c = OMP_CLAUSE_CHAIN (c))
+           {
+             if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
+               continue;
+             if (maybe_lookup_decl_in_outer_ctx (OMP_CLAUSE_DECL (c), ctx)
+                 == OMP_CLAUSE_DECL (detach_clause))
+               break;
+           }
+
+         if (c)
+           field = lookup_field (OMP_CLAUSE_DECL (c), ctx);
+         else
+           {
+             /* The detach event handle is not referenced within the
+                task context, so add a temporary field for it here.  */
+             field = build_decl (OMP_CLAUSE_LOCATION (detach_clause),
+                                 FIELD_DECL, NULL_TREE, ptr_type_node);
+             insert_field_into_struct (ctx->record_type, field);

Can't you just force the firstprivate clause during gimplification, so that
it doesn't go away even if not referenced?
That would mean just forcing in | GOVD_SEEN when it is added.
If not, not a big deal, just thought it could be easier.


I've tried this diff:

        case OMP_CLAUSE_DETACH:
-         decl = OMP_CLAUSE_DECL (c);
-         goto do_notice;
+         flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
+         goto do_add;

and just asserted that a suitable firstprivate clause is found in finish_taskreg_scan, and it seems to work fine :-).

+  #pragma omp task detach (x) detach (y) /* { dg-error "there can be at most one 
'detach' clause in a task construct" } */

It would be on a task construct rather than in a task construct, but the
common wording for this diagnostics is
"too many %qs clauses", "detach"
Please use that wording.

Done, though I don't see the point of using a %qs format code with a constant string here...

I have applied your other suggestions, and have retested the gomp.exp and libgomp tests. The full testrun started yesterday showed no regressions. If you have no further issues then I will commit this later tonight ahead of stage4.

Thanks

Kwok
commit 68f17e5d3f28b4150fc0fa9112671403c4519c05
Author: Kwok Cheung Yeung <k...@codesourcery.com>
Date:   Sat Jan 16 09:27:28 2021 -0800

    More task detach fixes.

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 4e9b21b..b938e6a 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -14942,8 +14942,7 @@ c_finish_omp_clauses (tree clauses, enum 
c_omp_region_type ort)
          if (detach_seen)
            {
              error_at (OMP_CLAUSE_LOCATION (c),
-                       "there can be at most one %<detach%> clause in a "
-                       "task construct");
+                       "too many %<detach%> clauses on a task construct");
              remove = true;
              break;
            }
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9dfaea2..c28cde0 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7425,8 +7425,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type 
ort)
          if (detach_seen)
            {
              error_at (OMP_CLAUSE_LOCATION (c),
-                       "there can be at most one %<detach%> clause in a "
-                       "task construct");
+                       "too many %<detach%> clauses on a task construct");
              remove = true;
              break;
            }
@@ -7436,8 +7435,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type 
ort)
              if (!type_dependent_expression_p (t)
                  && (!INTEGRAL_TYPE_P (type)
                      || TREE_CODE (type) != ENUMERAL_TYPE
-                     || DECL_NAME (TYPE_NAME (type))
-                          != get_identifier ("omp_event_handle_t")))
+                     || (DECL_NAME (TYPE_NAME (type))
+                         != get_identifier ("omp_event_handle_t"))))
                {
                  error_at (OMP_CLAUSE_LOCATION (c),
                            "%<detach%> clause event handle "
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 5fbe2fc..d2ac5f9 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -9764,8 +9764,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq 
*pre_p,
          break;
 
        case OMP_CLAUSE_DETACH:
-         decl = OMP_CLAUSE_DECL (c);
-         goto do_notice;
+         flags = GOVD_FIRSTPRIVATE | GOVD_SEEN;
+         goto do_add;
 
        case OMP_CLAUSE_IF:
          if (OMP_CLAUSE_IF_MODIFIER (c) != ERROR_MARK
diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
index ea0f058..7559ec8 100644
--- a/gcc/omp-expand.c
+++ b/gcc/omp-expand.c
@@ -860,9 +860,9 @@ expand_task_call (struct omp_region *region, basic_block bb,
 
   gsi = gsi_last_nondebug_bb (bb);
 
-  detach = detach
-          ? build_fold_addr_expr (OMP_CLAUSE_DECL (detach))
-          : null_pointer_node;
+  detach = (detach
+           ? build_fold_addr_expr (OMP_CLAUSE_DECL (detach))
+           : null_pointer_node);
 
   tree t = gimple_omp_task_data_arg (entry_stmt);
   if (t == NULL)
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 60a651f..c1267dc 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2436,24 +2436,8 @@ finish_taskreg_scan (omp_context *ctx)
                break;
            }
 
-         if (c)
-           field = lookup_field (OMP_CLAUSE_DECL (c), ctx);
-         else
-           {
-             /* The detach event handle is not referenced within the
-                task context, so add a temporary field for it here.  */
-             field = build_decl (OMP_CLAUSE_LOCATION (detach_clause),
-                                 FIELD_DECL, NULL_TREE, ptr_type_node);
-             insert_field_into_struct (ctx->record_type, field);
-
-             if (ctx->srecord_type)
-               {
-                 tree sfield
-                   = build_decl (OMP_CLAUSE_LOCATION (detach_clause),
-                                 FIELD_DECL, NULL_TREE, ptr_type_node);
-                 insert_field_into_struct (ctx->srecord_type, sfield);
-               }
-           }
+         gcc_assert (c);
+         field = lookup_field (OMP_CLAUSE_DECL (c), ctx);
 
          /* Move field corresponding to the detach clause first.
             This is filled by GOMP_task and needs to be in a
diff --git a/gcc/testsuite/c-c++-common/gomp/task-detach-1.c 
b/gcc/testsuite/c-c++-common/gomp/task-detach-1.c
index f50f748..4558bc1 100644
--- a/gcc/testsuite/c-c++-common/gomp/task-detach-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/task-detach-1.c
@@ -10,7 +10,7 @@ extern void omp_fulfill_event (omp_event_handle_t);
 
 void f (omp_event_handle_t x, omp_event_handle_t y, int z)
 {
-  #pragma omp task detach (x) detach (y) /* { dg-error "there can be at most 
one 'detach' clause in a task construct" } */
+  #pragma omp task detach (x) detach (y) /* { dg-error "too many 'detach' 
clauses on a task construct" } */
     ;
 
   #pragma omp task mergeable detach (x) /* { dg-error "'detach' clause must 
not be used together with 'mergeable' clause" } */
diff --git a/gcc/testsuite/g++.dg/gomp/task-detach-1.C 
b/gcc/testsuite/g++.dg/gomp/task-detach-1.C
index 2f0c650..6028cb4 100644
--- a/gcc/testsuite/g++.dg/gomp/task-detach-1.C
+++ b/gcc/testsuite/g++.dg/gomp/task-detach-1.C
@@ -7,7 +7,15 @@ typedef enum omp_event_handle_t
 } omp_event_handle_t;
 
 template <typename T>
-void func ()
+void foo ()
+{
+  T t;
+  #pragma omp task detach (t)
+    ;
+}
+
+template <typename T>
+void bar ()
 {
   T t;
   #pragma omp task detach (t) // { dg-error "'detach' clause event handle has 
type 'int' rather than 'omp_event_handle_t'" }
@@ -16,6 +24,6 @@ void func ()
 
 void f()
 {
-  func <omp_event_handle_t> ();
-  func <int> (); // { dg-message "required from here" }
+  foo <omp_event_handle_t> ();
+  bar <int> (); // { dg-message "required from here" }
 }
diff --git a/gcc/testsuite/gfortran.dg/gomp/task-detach-1.f90 
b/gcc/testsuite/gfortran.dg/gomp/task-detach-1.f90
index 114068e..4763f13 100644
--- a/gcc/testsuite/gfortran.dg/gomp/task-detach-1.f90
+++ b/gcc/testsuite/gfortran.dg/gomp/task-detach-1.f90
@@ -26,4 +26,4 @@ program task_detach_1
 
   !$omp task detach (x) shared (x) ! { dg-error "DETACH event handle 'x' in 
SHARED clause at \\\(1\\\)" }
   !$omp end task
-end program
\ No newline at end of file
+end program
diff --git a/libgomp/task.c b/libgomp/task.c
index f02c1ea..5ece878 100644
--- a/libgomp/task.c
+++ b/libgomp/task.c
@@ -2409,7 +2409,7 @@ omp_fulfill_event (omp_event_handle_t event)
   if (__atomic_load_n (sem, __ATOMIC_RELAXED))
     gomp_fatal ("omp_fulfill_event: %p event already fulfilled!\n", sem);
 
-  gomp_debug(0, "omp_fulfill_event: %p\n", sem);
+  gomp_debug (0, "omp_fulfill_event: %p\n", sem);
   gomp_sem_post (sem);
   if (team)
     gomp_team_barrier_wake (&team->barrier, 1);

Reply via email to