On Thu, Nov 18, 2021 at 07:30:36PM +0000, Hafiz Abid Qadeer wrote:
> +           if (gfc_match (" : ") != MATCH_YES)
> +             {
> +               /* If no ":" then there is no allocator, we backtrack
> +                  and read the variable list.  */
> +               gfc_free_expr (allocator);
> +               allocator = NULL;
> +               gfc_current_locus = old_loc;
> +             }

Ok, no leak above.

> +
> +           gfc_omp_namelist **head = NULL;
> +           m = gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_ALLOCATE],
> +                                            false, NULL, &head);
> +
> +           if (m == MATCH_ERROR)
> +             break;

But here it leaks.  Just call gfc_free_expr (allocator); before break.

> +
> +           gfc_omp_namelist *n;
> +           for (n = *head; n; n = n->next)
> +             if (allocator)
> +               n->expr = gfc_copy_expr (allocator);
> +             else
> +               n->expr = NULL;
> +           gfc_free_expr (allocator);
> +           continue;
> +         }
>         if ((mask & OMP_CLAUSE_AT)
>             && (m = gfc_match_dupl_check (c->at == OMP_AT_UNSET, "at", true))
>                != MATCH_NO)

> +  if (omp_clauses->lists[OMP_LIST_ALLOCATE])
> +    {
> +      for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
> +     if (n->expr && (n->expr->ts.type != BT_INTEGER
> +         || n->expr->ts.kind != gfc_c_intptr_kind))
> +       {
> +         gfc_error ("Expected integer expression of the "
> +             "'omp_allocator_handle_kind' kind at %L", &n->expr->where);

Formatting, "' should be indented below "Expected

> +         break;
> +       }
> +
> +      /* Check for 2 things here.
> +     1.  There is no duplication of variable in allocate clause.
> +     2.  Variable in allocate clause are also present in some
> +      privatization clase (non-composite case).  */
> +      for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
> +     n->sym->omp_allocate_clause = 0;
> +
> +      gfc_omp_namelist *prev = NULL;
> +      for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n;)
> +     {
> +       if (n->sym->omp_allocate_clause == 1)
> +         {
> +           gfc_warning (0, "%qs appears more than once in %<allocate%> "
> +                        "clauses at %L" , n->sym->name, &n->where);
> +           /* We have already seen this variable so it is a duplicate.
> +              Remove it.  */
> +           if (prev != NULL && prev->next == n)
> +             {
> +               prev->next = n->next;
> +               n->next = NULL;
> +               gfc_free_omp_namelist (n, 0);
> +               n = prev->next;
> +             }
> +           continue;
> +         }
> +       n->sym->omp_allocate_clause = 1;
> +       prev = n;
> +       n = n->next;
> +     }
> +
> +      /* non-composite constructs.  */
> +      if (code && code->op < EXEC_OMP_DO_SIMD)
> +     {
> +       for (list = 0; list < OMP_LIST_NUM; list++)
> +         switch (list)
> +         {
> +           case OMP_LIST_PRIVATE:
> +           case OMP_LIST_FIRSTPRIVATE:
> +           case OMP_LIST_LASTPRIVATE:
> +           case OMP_LIST_REDUCTION:
> +           case OMP_LIST_REDUCTION_INSCAN:
> +           case OMP_LIST_REDUCTION_TASK:
> +           case OMP_LIST_IN_REDUCTION:
> +           case OMP_LIST_TASK_REDUCTION:
> +           case OMP_LIST_LINEAR:
> +             for (n = omp_clauses->lists[list]; n; n = n->next)
> +               n->sym->omp_allocate_clause = 0;
> +             break;
> +           default:
> +             break;
> +         }
> +
> +       for (n = omp_clauses->lists[OMP_LIST_ALLOCATE]; n; n = n->next)
> +         if (n->sym->omp_allocate_clause == 1)
> +           gfc_error ("%qs specified in 'allocate' clause at %L but not "
> +                      "in an explicit privatization clause",
> +                      n->sym->name, &n->where);
> +     }
> +    }

Do you really need a new omp_allocate_clause bit?  From what I can see,
other code uses n->sym->mark for such purposes (temporarily marking some
symbols).
Also, I think allocate clause like the privatization clauses should allow
common blocks and I see code that uses the marks uses something like:
  for (list = OMP_LIST_TO; list != OMP_LIST_NUM;
       list = (list == OMP_LIST_TO ? OMP_LIST_LINK : OMP_LIST_NUM))
    for (n = c->lists[list]; n; n = n->next)
      if (n->sym)
        n->sym->mark = 0;
      else if (n->u.common->head)
        n->u.common->head->mark = 0;
So, a question is if the above won't just crash if I specify
  firstprivate(/foobar/) allocate(/foobar/)
etc.

> +     case OMP_LIST_ALLOCATE:
> +       for (; n != NULL; n = n->next)
> +         if (n->sym->attr.referenced || declare_simd)

!$omp declare simd doesn't allow allocate clause, so why the
above " || declare_simd"?

> +           {
> +             tree t = gfc_trans_omp_variable (n->sym, declare_simd);

And not , false); above?

        Jakub

Reply via email to