On Mon, Sep 11, 2023 at 03:21:54PM +0200, Tobias Burnus wrote:
> +      if (TREE_STATIC (var))
> +     {
> +       if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
> +         error_at (loc, "%<allocator%> clause required for "
> +                        "static variable %qD", var);
> +       else if (allocator
> +                && (tree_int_cst_sgn (allocator) != 1
> +                    || tree_to_shwi (allocator) > 8))

Has anything checked that in this case allocator is actually INTEGER_CST
which fits into shwi?  Otherwise tree_to_shwi will ICE.
Consider say allocator argument of
329857234985743598347598437598347594835743895743wb
or (((unsigned __int128) 0x123456789abcdef0) << 64)
Either tree_fits_shwi_p (allocator) check would do it, or perhaps
else if (allocator
         && TREE_CODE (allocator) == INTEGER_CST
         && wi::to_widest (allocator) > 0
         && wi::to_widest (allocator) <= 8)
?

> +      if (allocator
> +       && TREE_CODE (allocator) == VAR_DECL
> +       && c_check_in_current_scope (var))
> +     {
> +       if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
> +                                      DECL_SOURCE_LOCATION (allocator)))
> +         {
> +           error_at (OMP_CLAUSE_LOCATION (nl),
> +                     "allocator variable %qD must be declared before %qD",
> +                     allocator, var);
> +           inform (DECL_SOURCE_LOCATION (allocator),
> +                   "allocator declared here");
> +           inform (DECL_SOURCE_LOCATION (var), "declared here");
> +         }
> +       else
> +        {
> +          gcc_assert (cur_stmt_list
> +                      && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
> +          tree_stmt_iterator l = tsi_last (cur_stmt_list);
> +          while (!tsi_end_p (l))
> +            {
> +              if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
> +                                             DECL_SOURCE_LOCATION (var)))
> +                break;
> +              if (TREE_CODE (*l) == MODIFY_EXPR
> +                  && TREE_OPERAND (*l, 0) == allocator)
> +                {
> +                  error_at (EXPR_LOCATION (*l),
> +                            "allocator variable %qD, used in the "
> +                            "%<allocate%> directive for %qD, must not be "
> +                            "modified between declaration of %qD and its "
> +                            "%<allocate%> directive",
> +                            allocator, var, var);
> +                  inform (DECL_SOURCE_LOCATION (var), "declared here");
> +                  inform (OMP_CLAUSE_LOCATION (nl), "used here");
> +                  break;
> +               }
> +             --l;
> +          }
> +        }

BTW, it doesn't necessarily have to be just the simple case which you catch
here, namely that allocator is a VAR_DECL defined after var in current
scope.
One can have an expression which uses those other vars, say
  int v;
  int a = 1;
  int b[n]; // VLA
  b[a] = 5;
  #pragma omp allocate (v) allocator (foo (a, &b[a]))
where foo would be some function which returns omp_allocator_handle_t.
Or it could be e.g. lambda declared later, etc.
I bet we can't catch everything, but perhaps e.g. doing the first
diagnostics from within walk_tree might be better.

        Jakub

Reply via email to