]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR middle-end/89621 (ICE with allocatable character and openmp)
authorJakub Jelinek <jakub@redhat.com>
Fri, 30 Aug 2019 12:33:00 +0000 (14:33 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 30 Aug 2019 12:33:00 +0000 (14:33 +0200)
Backported from mainline
2019-03-28  Jakub Jelinek  <jakub@redhat.com>

PR middle-end/89621
* tree-inline.h (struct copy_body_data): Add
dont_remap_vla_if_no_change flag.
* tree-inline.c (remap_type_3, remap_type_2): New functions.
(remap_type): Don't remap vla types if id->dont_remap_vla_if_no_change
and remap_type_2 returns false.
* omp-low.c (new_omp_context): Set ctx->cb.dont_remap_vla_if_no_change.

* gfortran.dg/gomp/pr89621.f90: New test.

From-SVN: r275143

gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/gomp/pr89621.f90 [new file with mode: 0644]
gcc/tree-inline.c
gcc/tree-inline.h

index 36c445f3c7b3818fb01cf91c688fdbd2dd40826e..3832f25eed7f20bc85296d9c1792f8cfd7394dd3 100644 (file)
@@ -1,6 +1,16 @@
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-03-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/89621
+       * tree-inline.h (struct copy_body_data): Add
+       dont_remap_vla_if_no_change flag.
+       * tree-inline.c (remap_type_3, remap_type_2): New functions.
+       (remap_type): Don't remap vla types if id->dont_remap_vla_if_no_change
+       and remap_type_2 returns false.
+       * omp-low.c (new_omp_context): Set ctx->cb.dont_remap_vla_if_no_change.
+
        2019-03-20  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/89752
index 775951e12a8196d4999c30816198a055ee40f900..23a4e24e00b9f6cfe175ed81b163e52d40585a32 100644 (file)
@@ -853,6 +853,7 @@ new_omp_context (gimple *stmt, omp_context *outer_ctx)
       ctx->cb.copy_decl = omp_copy_decl;
       ctx->cb.eh_lp_nr = 0;
       ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
+      ctx->cb.dont_remap_vla_if_no_change = true;
       ctx->depth = 1;
     }
 
index 31598e87e70f7abe744c7c678967eaa61d785a37..0a2b800f679f0cc580c30512dd2770a22dd484df 100644 (file)
@@ -1,6 +1,11 @@
 2019-08-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2019-03-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/89621
+       * gfortran.dg/gomp/pr89621.f90: New test.
+
        2019-03-26  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/89796
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr89621.f90 b/gcc/testsuite/gfortran.dg/gomp/pr89621.f90
new file mode 100644 (file)
index 0000000..24ac18c
--- /dev/null
@@ -0,0 +1,18 @@
+! PR middle-end/89621
+! { dg-do compile }
+
+subroutine sub(str)
+  character(*), intent(in) :: str
+end subroutine sub
+
+program pr89621
+  implicit none
+  integer i
+  character(len=:), allocatable :: str
+  str = "test"
+  !$omp parallel do
+  do i = 1, 10
+    call sub(str)
+  enddo
+  !$omp end parallel do
+end program pr89621
index e12d2e9f5d6ae567a3126b2e7d16edd0b4edd8d2..cf87409baa2e9a048867c4a66c4e1f7f909d3182 100644 (file)
@@ -569,6 +569,92 @@ remap_type_1 (tree type, copy_body_data *id)
   return new_tree;
 }
 
+/* Helper function for remap_type_2, called through walk_tree.  */
+
+static tree
+remap_type_3 (tree *tp, int *walk_subtrees, void *data)
+{
+  copy_body_data *id = (copy_body_data *) data;
+
+  if (TYPE_P (*tp))
+    *walk_subtrees = 0;
+
+  else if (DECL_P (*tp) && remap_decl (*tp, id) != *tp)
+    return *tp;
+
+  return NULL_TREE;
+}
+
+/* Return true if TYPE needs to be remapped because remap_decl on any
+   needed embedded decl returns something other than that decl.  */
+
+static bool
+remap_type_2 (tree type, copy_body_data *id)
+{
+  tree t;
+
+#define RETURN_TRUE_IF_VAR(T) \
+  do                                                           \
+    {                                                          \
+      tree _t = (T);                                           \
+      if (_t)                                                  \
+       {                                                       \
+         if (DECL_P (_t) && remap_decl (_t, id) != _t)         \
+           return true;                                        \
+         if (!TYPE_SIZES_GIMPLIFIED (type)                     \
+             && walk_tree (&_t, remap_type_3, id, NULL))       \
+           return true;                                        \
+       }                                                       \
+    }                                                          \
+  while (0)
+
+  switch (TREE_CODE (type))
+    {
+    case POINTER_TYPE:
+    case REFERENCE_TYPE:
+    case FUNCTION_TYPE:
+    case METHOD_TYPE:
+      return remap_type_2 (TREE_TYPE (type), id);
+
+    case INTEGER_TYPE:
+    case REAL_TYPE:
+    case FIXED_POINT_TYPE:
+    case ENUMERAL_TYPE:
+    case BOOLEAN_TYPE:
+      RETURN_TRUE_IF_VAR (TYPE_MIN_VALUE (type));
+      RETURN_TRUE_IF_VAR (TYPE_MAX_VALUE (type));
+      return false;
+
+    case ARRAY_TYPE:
+      if (remap_type_2 (TREE_TYPE (type), id)
+         || (TYPE_DOMAIN (type) && remap_type_2 (TYPE_DOMAIN (type), id)))
+       return true;
+      break;
+
+    case RECORD_TYPE:
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+      for (t = TYPE_FIELDS (type); t; t = DECL_CHAIN (t))
+       if (TREE_CODE (t) == FIELD_DECL)
+         {
+           RETURN_TRUE_IF_VAR (DECL_FIELD_OFFSET (t));
+           RETURN_TRUE_IF_VAR (DECL_SIZE (t));
+           RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t));
+           if (TREE_CODE (type) == QUAL_UNION_TYPE)
+             RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t));
+         }
+      break;
+
+    default:
+      return false;
+    }
+
+  RETURN_TRUE_IF_VAR (TYPE_SIZE (type));
+  RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT (type));
+  return false;
+#undef RETURN_TRUE_IF_VAR
+}
+
 tree
 remap_type (tree type, copy_body_data *id)
 {
@@ -584,7 +670,10 @@ remap_type (tree type, copy_body_data *id)
     return *node;
 
   /* The type only needs remapping if it's variably modified.  */
-  if (! variably_modified_type_p (type, id->src_fn))
+  if (! variably_modified_type_p (type, id->src_fn)
+      /* Don't remap if copy_decl method doesn't always return a new
+        decl and for all embedded decls returns the passed in decl.  */
+      || (id->dont_remap_vla_if_no_change && !remap_type_2 (type, id)))
     {
       insert_decl_map (id, type, type);
       return type;
index ffb8333a7dd890841264c7eb69a0921d8f42bdf2..60a856ce79471f29f5e585fac3b050c504f91daf 100644 (file)
@@ -119,6 +119,13 @@ struct copy_body_data
   /* > 0 if we are remapping a type currently.  */
   int remapping_type_depth;
 
+  /* Usually copy_decl callback always creates new decls, in that case
+     we want to remap all variably_modified_type_p types.  If this flag
+     is set, remap_type will do further checks to see if remap_decl
+     of any decls mentioned in the type will remap to anything but itself
+     and only in that case will actually remap the type.  */
+  bool dont_remap_vla_if_no_change;
+
   /* A function to be called when duplicating BLOCK nodes.  */
   void (*transform_lang_insert_block) (tree);