This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PRs fortran/82972, fortran/83088, fortran/85851] Fix ICE with -finit-derived when using iso_c_binding


All,

The attached patch generates special initializers for derived-type
c_ptr and c_funptr symbols so they are handled correctly by the
translation phase. Previously, an EXPR_STRUCTURE expression was
generated for both types, as c_ptr and c_funptr are structure types
with a c_address field. The c_address field never had its backend_decl
generated, because it is typically handled specially.

With the patch, the trunk compiler does not exhibit the bugs in the
mentioned PRs (82972, 83088, 85851). I did encounter some issues
building and regression testing the trunk compiler which I am certain
are unrelated. The current trunk fails to bootstrap for me so I am
using an older revision which appears to have some testcase issues.
The issues are attached at the bottom of this e-mail for reference.

In any case, the changelog is here, and the patch is attached. Aside
from the issues mentioned below the compile bootstraps and regression
tests successfully. Does this look OK for trunk? Furthermore, this
patch comes a bit late as the PRs were submitted before 8.1 was
released; is it appropriate to backport this to 7-branch and/or
8-branch?


>From b6fbe8e429d5c98675741234e2ac5cc6810df3c5 Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Fri, 22 Jun 2018 16:11:02 -0400
Subject: [PATCH] PR fortran/82972

Fix -finit-derived for c_ptr and c_funptr in programs which use iso_c_binding.

gcc/fortran/
    * 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/
    * gfortran.dg/init_flag_17.f90: New testcase.
---
 gcc/fortran/expr.c                         | 33 +++++++++++++++++++++++++++++-
 gcc/testsuite/gfortran.dg/init_flag_17.f90 | 28 +++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/init_flag_17.f90


======= TEST ISSUES =======


$ gfortran --version
GNU Fortran (GCC) 8.0.0 20180110 (experimental)
...
$ make -sk check-fortran
...
FAIL: gfortran.dg/pr68078.f90   -O0  execution test
FAIL: gfortran.fortran-torture/compile/pr83081.f90,  -O3 -g
(internal compiler error)
...

In the first case (pr68078) the process appears to occasionally run
out of stack memory due to the setrlimit(), causing it to receive
SIGSEGV.

$ cd gcc/testsuite/gfortran.dg
$ gfortran pr68078.f90 set_vm_limit.c -o pr68078
$ i=0; time while ./a.out >/dev/null; do echo attempt $i; i=$(($i+1)) ; done
attempt 0
attempt 1
attempt 2
attempt 3
attempt 4
attempt 5
attempt 6
attempt 7
attempt 8
attempt 9
attempt 10
Segmentation fault (core dumped)

real    0m0.104s
user    0m0.007s
sys    0m0.023s

The second case appears positively unrelated (and only occurs with -O3):

$ gfortran -c -O3 pr83081.f90
during GIMPLE pass: pcom
pr83081.f90:4:0:

   Subroutine SPLIFT (X,Y,YP,YPP,N,IERR,ISX,A1,B1,AN,BN)

internal compiler error: in probability_in, at profile-count.h:1038
0x6f47ee profile_count::probability_in(profile_count) const
    /data/midas/foreese/src/gcc-trunk/gcc/profile-count.h:1038
0x6f47ee tree_transform_and_unroll_loop(loop*, unsigned int,
edge_def*, tree_niter_desc*, void (*)(loop*, void*), void*)
    /data/midas/foreese/src/gcc-trunk/gcc/tree-ssa-loop-manip.c:1382
0xe36716 tree_predictive_commoning_loop
    /data/midas/foreese/src/gcc-trunk/gcc/tree-predcom.c:3278
0xe37e7d tree_predictive_commoning()
    /data/midas/foreese/src/gcc-trunk/gcc/tree-predcom.c:3312
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.


======= END TEST ISSUES =======
From b6fbe8e429d5c98675741234e2ac5cc6810df3c5 Mon Sep 17 00:00:00 2001
From: Fritz Reese <fritzoreese@gmail.com>
Date: Fri, 22 Jun 2018 16:11:02 -0400
Subject: [PATCH] PR fortran/82972

Fix -finit-derived for c_ptr and c_funptr in programs which use iso_c_binding.

gcc/fortran/
	* 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/
	* gfortran.dg/init_flag_17.f90: New testcase.
---
 gcc/fortran/expr.c                         | 33 +++++++++++++++++++++++++++++-
 gcc/testsuite/gfortran.dg/init_flag_17.f90 | 28 +++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gfortran.dg/init_flag_17.f90

diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 45ccc184fc1..ad549911cd1 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -4476,7 +4476,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);
 }
 
 
@@ -4488,6 +4488,33 @@ 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
@@ -4498,8 +4525,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.  */
diff --git a/gcc/testsuite/gfortran.dg/init_flag_17.f90 b/gcc/testsuite/gfortran.dg/init_flag_17.f90
new file mode 100644
index 00000000000..401830fccbc
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/init_flag_17.f90
@@ -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" } }
-- 
2.12.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]