{
struct gomp_team *team = gomp_new_team (1);
struct gomp_task *task = thr->task;
+ struct gomp_task **implicit_task = &task;
struct gomp_task_icv *icv = task ? &task->icv : &gomp_global_icv;
team->prev_ts = thr->ts;
thr->ts.team = team;
thr->ts.static_trip = 0;
thr->task = &team->implicit_task[0];
gomp_init_task (thr->task, NULL, icv);
- if (task)
+ while (*implicit_task
+ && (*implicit_task)->kind != GOMP_TASK_IMPLICIT)
+ implicit_task = &(*implicit_task)->parent;
+ if (*implicit_task)
{
- thr->task = task;
+ thr->task = *implicit_task;
gomp_end_task ();
- free (task);
+ free (*implicit_task);
thr->task = &team->implicit_task[0];
}
else
pthread_setspecific (gomp_thread_destructor, thr);
+ if (implicit_task != &task)
+ {
+ *implicit_task = thr->task;
+ thr->task = task;
+ }
}
if (thr->ts.team
&& !thr->task->final_task)
struct gomp_task_icv *icv;
struct gomp_team *team = gomp_new_team (1);
struct gomp_task *task = thr->task;
+ struct gomp_task **implicit_task = &task;
icv = task ? &task->icv : &gomp_global_icv;
team->prev_ts = thr->ts;
thr->ts.team = team;
thr->ts.static_trip = 0;
thr->task = &team->implicit_task[0];
gomp_init_task (thr->task, NULL, icv);
- if (task)
+ while (*implicit_task
+ && (*implicit_task)->kind != GOMP_TASK_IMPLICIT)
+ implicit_task = &(*implicit_task)->parent;
+ if (*implicit_task)
{
- thr->task = task;
+ thr->task = *implicit_task;
gomp_end_task ();
- free (task);
+ free (*implicit_task);
thr->task = &team->implicit_task[0];
}
#ifdef LIBGOMP_USE_PTHREADS
else
pthread_setspecific (gomp_thread_destructor, thr);
#endif
+ if (implicit_task != &task)
+ {
+ *implicit_task = thr->task;
+ thr->task = task;
+ }
}
/* The format of data is:
--- /dev/null
+/* { dg-do run } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int a;
+
+int
+main ()
+{
+ #pragma omp task final (1)
+ {
+ if (!omp_in_final ())
+ abort ();
+ #pragma omp task
+ {
+ if (!omp_in_final ())
+ abort ();
+ #pragma omp taskgroup task_reduction (+: a)
+ {
+ if (!omp_in_final ())
+ abort ();
+ #pragma omp task in_reduction (+: a)
+ {
+ ++a;
+ if (!omp_in_final ())
+ abort ();
+ }
+ }
+ if (!omp_in_final ())
+ abort ();
+ #pragma omp taskwait
+ }
+ }
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+
+int a;
+
+int
+main ()
+{
+ #pragma omp task
+ {
+ #pragma omp taskgroup task_reduction (+: a)
+ {
+ #pragma omp task in_reduction (+: a)
+ ++a;
+ }
+ }
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+ #pragma omp task final (1)
+ {
+ if (!omp_in_final ())
+ abort ();
+ #pragma omp task
+ {
+ if (!omp_in_final ())
+ abort ();
+ #pragma omp target nowait
+ if (omp_in_final ())
+ abort ();
+ if (!omp_in_final ())
+ abort ();
+ #pragma omp taskwait
+ }
+ }
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+
+int
+main ()
+{
+ int i = 0;
+ #pragma omp task
+ {
+ #pragma omp target nowait private (i)
+ i = 1;
+ #pragma omp taskwait
+ }
+ return 0;
+}