Re: [Patch] C, C++, Fortran, OpenMP: Add support for device-modifiers for 'omp target device'

2021-07-20 Thread Jakub Jelinek via Fortran
On Wed, Jul 07, 2021 at 07:59:58PM +0200, Marcel Vollweiler wrote:
> OpenMP: Add support for device-modifiers for 'omp target device'
> 
> gcc/c/ChangeLog:
> 
>   * c-parser.c (c_parser_omp_clause_device): Add support for 
>   device-modifiers for 'omp target device'.
> 
> gcc/cp/ChangeLog:
> 
>   * parser.c (cp_parser_omp_clause_device): Add support for 
>   device-modifiers for 'omp target device'.
> 
> gcc/fortran/ChangeLog:
> 
>   * openmp.c (gfc_match_omp_clauses): Add support for 
>   device-modifiers for 'omp target device'.
> 
> gcc/testsuite/ChangeLog:
> 
>   * c-c++-common/gomp/target-device-1.c: New test.
>   * c-c++-common/gomp/target-device-2.c: New test.
>   * gfortran.dg/gomp/target-device-1.f90: New test.
>   * gfortran.dg/gomp/target-device-2.f90: New test.

>  static tree
>  c_parser_omp_clause_device (c_parser *parser, tree list)
>  {
>location_t clause_loc = c_parser_peek_token (parser)->location;
> +  location_t expr_loc;
> +  c_expr expr;
> +  tree c, t;
> +
>matching_parens parens;
> -  if (parens.require_open (parser))
> +  if (!parens.require_open (parser))
> +return list;
> +
> +  int pos = 1;
> +  int pos_colon = 0;
> +  while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME
> +  || c_parser_peek_nth_token_raw (parser, pos)->type == CPP_COLON
> +  || c_parser_peek_nth_token_raw (parser, pos)->type == CPP_COMMA)

Why CPP_COMMA?  The OpenMP 5.0/5.1/5.2 grammar only supports a single device
modifier.
So please simplify it to just an
  if (c_parser_next_token_is (parser, CPP_NAME)
  && c_parser_peek_2nd_token (parser, 2)->type == CPP_COLON)
   {
and check there just for the two modifiers.
  const char *p
= IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
  if (strcmp ("ancestor", p) == 0)
...
  else if (strcmp ("device-num", p) == 0)
;
  else
error_at (..., "expected % or %");
}
Similarly for C++.

Also, even if we sorry on device(ancestor: ...), it would be nice if you
in tree.h define OMP_CLAUSE_DEVICE_ANCESTOR macro (with
  (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE)->base.public_flag)
definition), set it, sorry later on it (e.g. omp-expand.c) only if it
survived till then (wasn't removed because of other errors) and diagnose
the various restrictions/requirements on device(ancestor:).
In particular:
1) that OMP_CLAUSE_DEVICE clauses with OMP_CLAUSE_DEVICE_ANCESTOR
   only appear on OMP_TARGET and not on other constructs
   (this can be easily tested e.g. during gimplification, when
   gimplify_scan_omp_clauses sees OMP_CLAUSE_DEVICE with
   OMP_CLAUSE_DEVICE_ANCESTOR and code != OMP_TARGET, diagnose)
2) that if after the usual fully folding the argument is INTEGER_CST,
   it is equal to 1 (the spec says must evaluate to 1, but doesn't say
   it has to be a constant, so it can evaluate to 1 at runtime but if it is
   a constant other than 1, we know it will not evaluate to 1); this can be
   done in *finish_omp_clauses
3) that omp_requires_mask has OMP_REQUIRES_REVERSE_OFFLOAD set; this should
   be checked during the parsing
4) only the device, firstprivate, private, defaultmap, and map clauses may
   appear on the construct; can be also done during gimplification, there is
   at most one device clause, so walking all clauses when we see
   OMP_CLAUSE_DEVICE_ANCESTOR is still linear complexity
5) no OpenMP constructs or calls to OpenMP API runtime routines are allowed 
inside
   the corresponding target region (this is something that should be checked
   in omp-low.c region nesting code, we already have similar restrictions
   for e.g. the loop construct)
Everything should be covered by testcases.

Jakub



[PATCH] PR fortran/101514 - ICE: out of memory allocating 18446744073709551600 bytes

2021-07-20 Thread Harald Anlauf via Fortran
While investigating one of Gerhard's latest bug reports, which was almost
obvious to fix after a hint by Richard Biener, I found further variants of
valid and invalid code that lead to either NULL pointer dereferences or
similar OOM situations.

Regtested on x86_64-pc-linux-gnu.  OK for mainline / 11-branch?

Thanks,
Harald


Fortran: ICE, OOM while calculating sizes of derived type array components

gcc/fortran/ChangeLog:

PR fortran/101514
* target-memory.c (gfc_interpret_derived): Size of array component
of derived type can only be computed here for explicit size.
* trans-types.c (gfc_get_nodesc_array_type): Do not dereference
NULL pointers.

gcc/testsuite/ChangeLog:

PR fortran/101514
* gfortran.dg/pr101514.f90: New test.

diff --git a/gcc/fortran/target-memory.c b/gcc/fortran/target-memory.c
index cfa8402dd3f..7b21a9e04e8 100644
--- a/gcc/fortran/target-memory.c
+++ b/gcc/fortran/target-memory.c
@@ -534,6 +534,9 @@ gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *resu
 	{
 	  int n;

+	  if (cmp->as->type != AS_EXPLICIT)
+	return 0;
+
 	  e->expr_type = EXPR_ARRAY;
 	  e->rank = cmp->as->rank;

diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index d715838a046..50fda4328f7 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -1644,7 +1644,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
   GFC_TYPE_ARRAY_STRIDE (type, n) = tmp;

   expr = as->lower[n];
-  if (expr->expr_type == EXPR_CONSTANT)
+  if (expr && expr->expr_type == EXPR_CONSTANT)
 {
   tmp = gfc_conv_mpz_to_tree (expr->value.integer,
   gfc_index_integer_kind);
@@ -1694,7 +1694,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed,
   for (n = as->rank; n < as->rank + as->corank; n++)
 {
   expr = as->lower[n];
-  if (expr->expr_type == EXPR_CONSTANT)
+  if (expr && expr->expr_type == EXPR_CONSTANT)
 	tmp = gfc_conv_mpz_to_tree (expr->value.integer,
 gfc_index_integer_kind);
   else
diff --git a/gcc/testsuite/gfortran.dg/pr101514.f90 b/gcc/testsuite/gfortran.dg/pr101514.f90
new file mode 100644
index 000..51fbf8a7e85
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr101514.f90
@@ -0,0 +1,35 @@
+! { dg-do compile }
+! PR fortran/101514 - ICE: out of memory allocating ... bytes
+
+subroutine s
+  type t1
+ integer :: a(..) ! { dg-error "must have an explicit shape" }
+  end type
+  type t2
+ integer :: a(*)  ! { dg-error "must have an explicit shape" }
+  end type
+  type t3
+ integer :: a(:)  ! { dg-error "must have an explicit shape" }
+  end type
+  type t4
+ integer :: a(0:) ! { dg-error "must have an explicit shape" }
+  end type
+  type t5
+ integer, allocatable :: a(:)
+  end type
+  type t6
+ integer, pointer :: a(:)
+  end type
+  type(t1) :: a1
+  type(t2) :: a2
+  type(t3) :: a3
+  type(t4) :: a4
+  type(t5) :: a5
+  type(t6) :: a6
+  a1 = transfer(1, a1)
+  a2 = transfer(1, a2)
+  a3 = transfer(1, a3)
+  a4 = transfer(1, a4)
+  a5 = transfer(1, a5)
+  a6 = transfer(1, a6)
+end