[gfortran,patch] PR 25716: Implicit kind conversions in in expressions written to *.mod-files

Erik Edelmann erik.edelmann@iki.fi
Sun Jan 15 20:24:00 GMT 2006


:ADDPATCH fortran:

Here's a patch for PR 25716, a problem uncovered by the testcase
char_result_11.f90 on 64-bit processors.  The problem was
writting expressions containing function nodes calling a
__convert_X_Y function (to convert from from one type/kind to
another).  There where two problems with these nodes:

1) In resolve.c (gfc_resolve_index), when we create the type-spec
for the expression node, we don't initialize it properly, leaving
ts->cl non-NULL when it should be NULL.  Fixed by inserting a
call to gfc_clear_ts().

2) The expression node didn't get a symtree, which caused
problems in module.c (mio_expr) for function nodes when we call
mio_symtree_ref().  To fix this I inserted code to add a symtree
in intrinsic.c (gfc_convert_type_warn).  To make this work I had
to fix two other things as well:  

        a) Remove a symbol from the 'changed_syms' list when we
        free it in symbol.c (gfc_free_symbol) 

        b) In intrinsic.c (gfc_find_function), look for the
        function in the table 'conversion', if not found in
        the table 'functions'.

I do not provide a separate testcase for this, instead I've
modified char_result_11.f90 to fail (without this patch) an all
systems, by declaring some of the integer variables to have
kind=1 (which will induce kind-conversions where these variables
are used as array indeces; I presume that array index kind is
different from 1 on all systems.).  In addition I changed it from
{ dg-do compile } to { dg-do link }, because a problem with an
earlier version of the patch didn't turn up until linking.

I have regression tested the patch on Linux/x86, on 4.2 and 4.1.
In addition I have tested a few selected testcases on a cross
compiler to SPARC64, and in a comment in bugzilla Eric Botcazou
says the he has run the testsuite on 32-bit and 64-bit SPARC.

Ok to commit?


        Erik


2005-01-15  Erik Edelmann  <eedelman@gcc.gnu.org>

        PR fortran/25716
        * intrinsic.c (gfc_find_function): Search in 'conversion'
        if not found in 'functions'.
        (gfc_convert_type_warn): Add a symtree to the new
        expression node.
        * symbol.c (remove_from_changed_syms): New function.
        (gfc_free_symbol): Use it.
        * resolve.c (gfc_resolve_index): Clear the type-spec of
        the expression node first.


2005-01-15  Erik Edelmann  <eedelman@gcc.gnu.org>

        PR fortran/25716
        * gfortran.dg/char_result_11.f90: Make it sensitive to PR
        25716 on 32-bit systems too.
-------------- next part --------------
Index: gcc/testsuite/gfortran.dg/char_result_11.f90
===================================================================
--- gcc/testsuite/gfortran.dg/char_result_11.f90	(revision 109727)
+++ gcc/testsuite/gfortran.dg/char_result_11.f90	(working copy)
@@ -1,5 +1,6 @@
-! { dg-do compile }
-! PR 23675: Character function of module variable length
+! { dg-do link }
+! PR 23675: Character function of module-variable length
+! PR 25716: Implicit kind conversions in in expressions written to *.mod-files.
 module cutils
 
     implicit none
@@ -11,7 +12,8 @@ module cutils
     end type t
 
     integer :: m1 = 25, m2 = 25, m3 = 25, m4 = 25, m5 = 25
-    integer :: n1 = 3, n2 = 3, n3 = 3, n4 = 3, n5 = 3, n6 = 3, n7 = 3, n8 = 3, n9 = 3
+    integer :: n5 = 3, n7 = 3, n9 = 3
+    integer(1) :: n1 = 3, n2 = 3, n3 = 3, n4 = 3, n6 = 3, n8 = 3
     character(10) :: s = "abcdefghij"
     integer :: x(4) = (/ 30, 40, 50, 60 /)
     type(t) :: tt1(5), tt2(5)
Index: gcc/fortran/intrinsic.c
===================================================================
--- gcc/fortran/intrinsic.c	(revision 109727)
+++ gcc/fortran/intrinsic.c	(working copy)
@@ -711,8 +711,13 @@ find_sym (gfc_intrinsic_sym * start, int
 gfc_intrinsic_sym *
 gfc_find_function (const char *name)
 {
+  gfc_intrinsic_sym *sym;
+
+  sym = find_sym (functions, nfunc, name);
+  if (!sym)
+    sym = find_sym (conversion, nconv, name);
 
-  return find_sym (functions, nfunc, name);
+  return sym;
 }
 
 
@@ -3415,6 +3420,15 @@ gfc_convert_type_warn (gfc_expr * expr, 
   new->rank = rank;
   new->shape = gfc_copy_shape (shape, rank);
 
+  gfc_get_sym_tree (sym->name, gfc_current_ns, &new->symtree);
+  new->symtree->n.sym->ts = *ts;
+  new->symtree->n.sym->attr.flavor = FL_PROCEDURE;
+  new->symtree->n.sym->attr.function = 1;
+  new->symtree->n.sym->attr.intrinsic = 1;
+  new->symtree->n.sym->attr.elemental = 1;
+  new->symtree->n.sym->attr.pure = 1;
+  new->symtree->n.sym->attr.referenced = 1;
+
   *expr = *new;
 
   gfc_free (new);
Index: gcc/fortran/symbol.c
===================================================================
--- gcc/fortran/symbol.c	(revision 109727)
+++ gcc/fortran/symbol.c	(working copy)
@@ -1820,6 +1820,30 @@ gfc_find_uop (const char *name, gfc_name
 }
 
 
+/* Remove a symbol from the 'changed_syms' list */
+
+static void
+remove_from_changed_syms (gfc_symbol * sym)
+{
+  gfc_symbol *p, *q;
+
+  q = NULL;
+  for (p = changed_syms; p; p = p->tlink)
+    {
+      if (p == sym) 
+        {
+          if (q)
+            q->tlink = p->tlink;
+          else
+            changed_syms = p->tlink;
+
+          return;
+        }
+      q = p;
+    }
+}
+
+
 /* Remove a gfc_symbol structure and everything it points to.  */
 
 void
@@ -1843,6 +1867,8 @@ gfc_free_symbol (gfc_symbol * sym)
 
   gfc_free_formal_arglist (sym->formal);
 
+  remove_from_changed_syms (sym);
+
   gfc_free (sym);
 }
 
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 109727)
+++ gcc/fortran/resolve.c	(working copy)
@@ -2041,6 +2041,7 @@ gfc_resolve_index (gfc_expr * index, int
   if (index->ts.kind != gfc_index_integer_kind
       || index->ts.type != BT_INTEGER)
     {
+      gfc_clear_ts (&ts);
       ts.type = BT_INTEGER;
       ts.kind = gfc_index_integer_kind;
 


More information about the Fortran mailing list