Fix -finit-derived for c_ptr and c_funptr in programs which use
authorFritz Reese <fritzoreese@gmail.com>
Mon, 25 Jun 2018 18:33:11 +0000 (18:33 +0000)
committerFritz Reese <foreese@gcc.gnu.org>
Mon, 25 Jun 2018 18:33:11 +0000 (18:33 +0000)
    iso_c_binding.

    gcc/fortran/ChangeLog:

    2018-06-25  Fritz Reese  <fritzoreese@gmail.com>

PR fortran/82972
        PR fortran/83088
        PR fortran/85851
* expr.c (component_initializer): Assign init expr to c->initializer.
(generate_isocbinding_initializer): New.
(gfc_generate_initializer): Call generate_isocbinding_initializer to
generate initializers for c_ptr and c_funptr with -finit-derived.

    gcc/testsuite/ChangeLog:

    2018-06-25  Fritz Reese  <fritzoreese@gmail.com>

PR fortran/82972
        PR fortran/83088
        PR fortran/85851
* gfortran.dg/init_flag_17.f90: New testcase.

From-SVN: r262104

gcc/fortran/ChangeLog
gcc/fortran/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/init_flag_17.f90 [new file with mode: 0644]

index a214863da8cc95124d179f804adc90974d54a072..f052cfed2c86eada7eafd546540dbc1a4e855679 100644 (file)
@@ -1,3 +1,13 @@
+2018-06-25  Fritz Reese  <fritzoreese@gmail.com>
+
+       PR fortran/82972
+       PR fortran/83088
+       PR fortran/85851
+       * expr.c (component_initializer): Assign init expr to c->initializer.
+       (generate_isocbinding_initializer): New.
+       (gfc_generate_initializer): Call generate_isocbinding_initializer to
+       generate initializers for c_ptr and c_funptr with -finit-derived.
+
 2018-06-23  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/85983
index a1336d27859deaae2b677fa7f2f57aa2e5a9777e..a799a497bb8f8bdbf477133bb120e535a3f95f05 100644 (file)
@@ -4493,7 +4493,7 @@ component_initializer (gfc_typespec *ts, gfc_component *c, bool generate)
       gfc_apply_init (&c->ts, &c->attr, init);
     }
 
-  return init;
+  return (c->initializer = init);
 }
 
 
@@ -4505,6 +4505,32 @@ gfc_default_initializer (gfc_typespec *ts)
   return gfc_generate_initializer (ts, false);
 }
 
+/* Generate an initializer expression for an iso_c_binding type
+   such as c_[fun]ptr. The appropriate initializer is c_null_[fun]ptr.  */
+
+static gfc_expr *
+generate_isocbinding_initializer (gfc_symbol *derived)
+{
+  /* The initializers have already been built into the c_null_[fun]ptr symbols
+     from gen_special_c_interop_ptr.  */
+  gfc_symtree *npsym = NULL;
+  if (0 == strcmp (derived->name, "c_ptr"))
+    gfc_find_sym_tree ("c_null_ptr", gfc_current_ns, true, &npsym);
+  else if (0 == strcmp (derived->name, "c_funptr"))
+    gfc_find_sym_tree ("c_null_funptr", gfc_current_ns, true, &npsym);
+  else
+    gfc_internal_error ("generate_isocbinding_initializer(): bad iso_c_binding"
+                       " type, expected %<c_ptr%> or %<c_funptr%>");
+  if (npsym)
+    {
+      gfc_expr *init = gfc_copy_expr (npsym->n.sym->value);
+      init->symtree = npsym;
+      init->ts.is_iso_c = true;
+      return init;
+    }
+
+  return NULL;
+}
 
 /* Get or generate an expression for a default initializer of a derived type.
    If -finit-derived is specified, generate default initialization expressions
@@ -4515,8 +4541,12 @@ gfc_generate_initializer (gfc_typespec *ts, bool generate)
 {
   gfc_expr *init, *tmp;
   gfc_component *comp;
+
   generate = flag_init_derived && generate;
 
+  if (ts->u.derived->ts.is_iso_c && generate)
+    return generate_isocbinding_initializer (ts->u.derived);
+
   /* See if we have a default initializer in this, but not in nested
      types (otherwise we could use gfc_has_default_initializer()).
      We don't need to check if we are going to generate them.  */
index 9d3d16e0b038b81981606bc22b6d7b4638336b36..f2d9caffc0e3bd4521307a687dcd6471ff637012 100644 (file)
@@ -1,4 +1,9 @@
-gcc/testsuite/ChangeLog:
+2018-06-25  Fritz Reese  <fritzoreese@gmail.com>
+
+       PR fortran/82972
+       PR fortran/83088
+       PR fortran/85851
+       * gfortran.dg/init_flag_17.f90: New testcase.
 
 2018-06-25  Carl Love  <cel@us.ibm.com>
 
diff --git a/gcc/testsuite/gfortran.dg/init_flag_17.f90 b/gcc/testsuite/gfortran.dg/init_flag_17.f90
new file mode 100644 (file)
index 0000000..401830f
--- /dev/null
@@ -0,0 +1,28 @@
+! { dg-do compile }
+! { dg-options "-finit-derived -finit-local-zero -fdump-tree-original" }
+!
+! PR fortran/82972
+!
+! Make sure we do not ICE when generating initializers for c_ptr and c_funptr
+! components of derived types (and make sure they are properly initialized to
+! zero).
+!
+
+program init_flag_17
+  use iso_c_binding
+  implicit none
+
+  type :: ty
+    type(c_ptr)    :: ptr  ! = c_null_ptr
+    type(c_funptr) :: fptr ! = c_null_funptr
+  end type
+
+  type(ty) :: t
+
+  print *, t%ptr
+  print *, t%fptr
+
+end program
+
+! { dg-final { scan-tree-dump "\.ptr=0" "original" } }
+! { dg-final { scan-tree-dump "\.fptr=0" "original" } }