Bug 41777

Summary: Wrong-code with POINTER-returning GENERIC function
Product: gcc Reporter: Tobias Burnus <burnus>
Component: fortranAssignee: Tobias Burnus <burnus>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, mrestelli
Priority: P3 Keywords: rejects-valid, wrong-code
Version: 4.5.0   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: 4.2.1 4.3.3 4.4.2 4.5.0 Last reconfirmed: 2009-10-25 14:33:13
Bug Depends on: 41772    
Bug Blocks: 32834, 42361    
Attachments: Slightly reduced test case - needs now only FoX
Better patch
New, non-reduced test case

Description Tobias Burnus 2009-10-21 08:41:41 UTC
Non-reduced test case.

This is with http://static.exciting-code.org/exciting.hydrogen.9.10.tar.gz
Untar, cp build/platform/make.inc.g95 build/platform/make.inc.gfortran and adapt that file; run 'make'.

Note: Due to PR 41772, one needs to use the PGI loop in
src/FoX/fsys/fox_m_fsys_array_str.F90's "str_vs"
rather than TRANSFER.

cd examples/Al; ../../build/serial/exciting

Expected: Runs through successfully (as with g95, xlf90, ifort),
Actual result: Fails when FoX tries to remove a node ("NOT_FOUND_ERR").

As in PR 41772, I will try to get a small testcase. This time, valgrind is silent which does not help :-(
Comment 1 Tobias Burnus 2009-10-21 09:10:52 UTC
Created attachment 18851 [details]
Slightly reduced test case - needs now only FoX

Reduced test case -- still pretty large, but now only depends on FoX. Use similarly to PR 41772:

wget http://www.uszla.me.uk/FoX/source/FoX-4.0.4.tar.gz
tar xfz FoX-4.0.4.tar.gz
cd FoX-4.0.4 && ./configure FC=gfortran && make -j4

gfortran -Iobjs/finclude fox.f90 objs/lib/libFoX_{dom,utils,sax,common,fsys}.a
./a.out

In order to see better what goes wrong, patch dom/m_dom_dom.F90's removeChild by adding the PRINT statements:

    do i = 1, size(arg%childNodes%nodes)
      print *, 'removeChild: Walking list, i = ', i
      if (associated(arg%childNodes%nodes(i)%this, oldChild)) then
        print *, 'removeChild: Walking list, fount it, i_t = ', i_t

The gfortran output is then:

 removeChild: Walking list, i =            1
 [...]
 removeChild: Walking list, i =            9
NOT_FOUND_ERR

While g95/NAG f95 have:
 removeChild: Walking list, i =  1
 [...]
 removeChild: Walking list, fount it, i_t =  4
 [...]
  removeChild: Walking list, i =  9
FoX_NODE_IS_NULL

(Afterwards, all core dump. The result that it = 4 is found, can also be seen with the full program, where no segfault occurs.)

The needed input.xml can be found in attachment 18846 [details] of PR 41772
Comment 2 Tobias Burnus 2009-10-21 09:12:36 UTC
(In reply to comment #1)
> wget http://www.uszla.me.uk/FoX/source/FoX-4.0.4.tar.gz
> cd FoX-4.0.4 && ./configure FC=gfortran && make -j4

I forgot to re-mention that one needs to patch fsys/fox_m_fsys_array_str.F90's "str_vs" -> comment 0 (or PR 41772 needs to be fixed). Otherwise, it crashes before.
Comment 3 Tobias Burnus 2009-10-21 09:22:20 UTC
No regression, segfaults immediately with 4.2; shows the same behaviour for 4.3, 4.4 and 4.5.
Comment 4 Tobias Burnus 2009-10-21 12:08:48 UTC
Reduced test case. The problem is the GENERIC INTERFACE. For some reason,  the result attribute is not properly propagated. This leads to the bogus error:


print *, associated(a,f(a)) ! Valid, but error
                      1
Error: 'target' argument of 'associated' intrinsic at (1) must be a POINTER or a TARGET


and to the wrong code by printing "T F" instead of "T T".


module m
type t2
 integer :: i
end type t2
interface f
 module procedure f2
end interface f
contains
function f2(a)
  type(t2), pointer :: f2,a
  f2 => a
end function f2
end module m

use m
implicit none
type(t2), pointer :: a
allocate(a)
!print *, associated(a,f(a)) ! Valid, but error
call cmpPtr(a,f2(a))         ! "T" which is OK
call cmpPtr(a,f(a))          ! "F" which is wrong
contains
  subroutine cmpPtr(a,b)
    type(t2), pointer :: a,b
    print *, associated(a,b)
  end subroutine cmpPtr
end
Comment 5 Tobias Burnus 2009-10-25 14:33:13 UTC
  print *, associated(a,f(a)) ! Valid, but error

If one steps in the debugger, one see that the TARGET= argument of associate but "f", i.e. target->expr_type == EXPR_FUNCTION, target->symtree->n.sym->name "f" and target->value.function->esym->name == "f".

Patch - not regtested, but seems to work.

--- resolve.c   (Revision 153537)
+++ resolve.c
@@ -1867,6 +1867,11 @@ resolve_generic_f0 (gfc_expr *expr, gfc_
        {  
          expr->value.function.name = s->name;
          expr->value.function.esym = s;
+         /* Copy attributes such that checking attr.pointer works, but keep
+            attr.generic as we do not (want to) copy all the other properties
+            of the specific.  */
+         expr->symtree->n.sym->attr = s->attr;
+         expr->symtree->n.sym->attr.generic = 1;
          if (s->ts.type != BT_UNKNOWN)
            expr->ts = s->ts;
Comment 6 Tobias Burnus 2009-10-25 14:44:41 UTC
TODO: Check whether the patch does the right thing. One overrides the symbol settings of the generic, which should be harmless, but might lead to problems if one uses different specifics which share the same "sym" pointer. On the other hand, all the code assumes that accessing "symtree->n.sym->attr" gives the correct result for exec_type == EXEC_FUNCTION.
Comment 7 Dominique d'Humieres 2009-10-25 18:34:18 UTC
With the patch in comment #5 I got two extra errors for my tests:

modification of pr30793 (comment #7)

pr30793_red.f90:151.10:

  mshp => msh_(quality)
          1
Error: Function 'msh_' at (1) has no IMPLICIT type

and the pr40440, both the file requiring iso_varying_string.f95 and the one including it:

pr40440.f90:69.42:

    call ifile_append_from_string (ifile, var_str (trim (char)))
                                          1
Error: Function 'var_str' at (1) has no IMPLICIT type
pr40440.f90:116.62:

  use ifiles, only: line_p, line_init, line_get_string_advance
                                                              1
Fatal Error: Can't open module file 'ifiles.mod' for reading at (1): No such file or directory
Comment 8 Tobias Burnus 2009-10-28 10:17:43 UTC
Created attachment 18925 [details]
Better patch

Better fix. I think there are more of such problems around, but I won't fix them now :-)
Comment 9 Tobias Burnus 2009-10-28 10:38:03 UTC
> +    attr1 = gfc_expr_attr (target);

s/target/pointer/

I am now regtesting and will re-read and submit the patch afterwards.

(Writing patches in the early morning jet-lagged via a very slow internet connection does not work, cf. comment 5. But writing - newly jet-lagged - a patch without regtesting via a fast connection does not work either, cf. above.)
Comment 10 Tobias Burnus 2009-10-28 15:03:21 UTC
Created attachment 18926 [details]
New, non-reduced test case

Patch in comment 8 + fix in comment 9 regtests and fixes:
a) The fully reduced test case of comment 4
b) The partially reduced test case of comment 1

It does not fix the attached test case, which is a slightly modified version of comment 1 - and which still needs FoX to be installed and input.xml of attachment 18846 [details] of PR 41772. The loc lines show:

 loc thisnode:               6945920
 loc item    :       140736865394032

And the second one is clearly wrong. If one does not nest the arguments, but saves "getElementsByTagname" as "np" and uses it in turn for "item()", everything works as expected.

(Needless to say that the full program of comment 0 still does not work.)
Comment 11 Tobias Burnus 2009-10-28 15:47:18 UTC
Related problem:
  print *, loc(f2(a)) ! OK
  print *, loc(f (a)) ! Error "must be a variable"
The second line uses a generic function with "f2" being the specific one.

The problem is that gfc_check_loc calls check_variable, which checks whether function name = result name. I think this check is bogus. I think the purpose is to allow:
  function_name = value   ! in "function function_name" !
but for
  value = function_name(bar)  ! or LOC(function_name(bar))
it does not matter whether sym == sym->result.

On the other hand, if one is outside of "function function_name"
  func(function_name)
is something different (= function and not result) and there it does not matter whether sym == sym->result or not.

For the the example above, the patch below fixes it, but see caveat above.

Index: check.c
===================================================================
--- check.c     (revision 153645)
+++ check.c     (working copy)
@@ -288,7 +288,10 @@ variable_check (gfc_expr *e, int n)
   if ((e->expr_type == EXPR_VARIABLE
        && e->symtree->n.sym->attr.flavor != FL_PARAMETER)
       || (e->expr_type == EXPR_FUNCTION
-         && e->symtree->n.sym->result == e->symtree->n.sym))
+         && ((!e->value.function.esym
+              && e->value.function.esym->result == e->value.function.esym)
+             || (e->value.function.esym
+                 && e->symtree->n.sym->result == e->symtree->n.sym))))
     return SUCCESS;

   if (e->expr_type == EXPR_VARIABLE
Comment 12 Dominique d'Humieres 2009-10-28 16:27:05 UTC
> +         && ((!e->value.function.esym

is the ! at the right place? If e->value.function.esym == 0, would not
e->value.function.esym->result == e->value.function.esym
gives a bus error/segmentation fault?
Comment 13 Tobias Burnus 2009-10-29 15:24:55 UTC
Subject: Bug 41777

Author: burnus
Date: Thu Oct 29 15:24:38 2009
New Revision: 153706

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153706
Log:
2009-10-29  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41777
        * trans-expr.c
        * (gfc_conv_procedure_call,gfc_conv_expr_reference):
        Use for generic EXPR_FUNCTION the attributes of the specific
        function.

2009-10-29  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41777
        gfortran.dg/associated_target_3.f90: New testcase.


Added:
    trunk/gcc/testsuite/gfortran.dg/associated_target_3.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/check.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog

Comment 14 Tobias Burnus 2009-10-29 15:28:27 UTC
Committed attachment 18925 [details]. As written in comment 10 (and later), that patch fixes the reduced test case from comment 1 but not the original one (comment 0), nor the LOC issue nor the half-working new example of comment 10. [When debugging, I also found PR 41869.]
Comment 15 Tobias Burnus 2009-10-29 16:44:00 UTC
(In reply to comment #14)
> As written in comment 10 (and later), that patch
> fixes the reduced test case from comment 1 but not the original one (comment
> 0)

Actually, it seems to work now correctly with the current trunk - I will fix comment 10 and the LOC issue, however.
Comment 16 Tobias Burnus 2009-10-30 15:18:27 UTC
Subject: Bug 41777

Author: burnus
Date: Fri Oct 30 15:18:09 2009
New Revision: 153756

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=153756
Log:
2009-10-30  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41777
        * trans-expr.c
        * (gfc_conv_procedure_call,gfc_conv_expr_reference):
        Use for generic EXPR_FUNCTION the attributes of the specific
        function.

2009-10-30  Tobias Burnus  <burnus@net-b.de>

        PR fortran/41777
        gfortran.dg/associated_target_3.f90: New testcase.


Added:
    branches/gcc-4_4-branch/gcc/testsuite/gfortran.dg/associated_target_3.f90
Modified:
    branches/gcc-4_4-branch/gcc/fortran/ChangeLog
    branches/gcc-4_4-branch/gcc/fortran/check.c
    branches/gcc-4_4-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog

Comment 17 mrestelli 2009-11-27 14:28:23 UTC
*** Bug 40850 has been marked as a duplicate of this bug. ***
Comment 18 Tobias Burnus 2010-02-02 10:00:02 UTC
CLOSE as FIXED. 

Regarding comment 10: See newly opened PR 42934.
Comment 19 Tobias Burnus 2010-02-02 10:00:45 UTC
Really close the PR.