Bug 37926 - Program gives wrong output (connected to char len)
Program gives wrong output (connected to char len)
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.4.0
: P3 normal
: ---
Assigned To: Paul Thomas
: wrong-code
Depends on:
Blocks: 32834
  Show dependency treegraph
 
Reported: 2008-10-27 10:15 UTC by janus
Modified: 2008-11-24 19:20 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-11-14 19:00:42


Attachments
A prototype patch (2.03 KB, patch)
2008-11-15 05:57 UTC, Paul Thomas
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description janus 2008-10-27 10:15:54 UTC
Consider the following code:


module m

contains

  pure integer function mysize(a)
    integer,intent(in) :: a(:)
    mysize = size(a)
  end function

end module


program prog

use m
implicit none

character(3) :: str

integer :: i(3) = (/1,2,3/)

str = p(i,mysize)

print *,str,len(str)

contains

  function p(y,asz)
    implicit none
    integer :: y(:)
    interface
      pure integer function asz(c)
        integer,intent(in) :: c(:)
      end function
    end interface
    character(asz(y)) p
    integer i
    do i=1,asz(y)
      print *,y(i),achar(iachar('A')+y(i))
      p(i:i) = achar(iachar('A')+y(i))
    end do
    print *,p,len(p)
  end function

end


Compiling this with GCC trunk rev. 141361 does work, but when running the produced binary the output is:

           1 B
           2 C
           3 D
 BCD           3
 B             3

The first four lines are ok, but the last one should actually be equal to the second to last one.

The program does give the expected ouput when the implementation of mysize is changed such that it always returns a constant (e.g. "3").

Compiling with 4.3.1 gives an ICE.
Compiling with g95 works and gives the right output.
Comment 1 Tobias Burnus 2008-10-27 22:19:10 UTC
Confirm. Works also with NAG f95 and ifort; does not compile with openf95, ICEs with sunf95 and gfortran 4.1/4.2.

    D.1627 = mysize (D.1625);
    [...]
    D.1650 = MAX_EXPR <D.1627, 0>;
    p (pstr.23, D.1650, D.1616, mysize);
    D.1632 = MAX_EXPR <D.1627, 0>;
    if (D.1632 > 2) goto <D.1651>; else goto <D.1652>;

I don't understand the dump. Why is D.1627 and not D.1650 used for D.1532? Any why is there is "D.1650 = MAX_EXPR <D.1627, 0>;" for the result variable. It probably does not harm, but it does not make sense either. (Still, I don't see why D.1532 is (presumably) "1" and not "3".)
Comment 2 Paul Thomas 2008-10-28 18:42:57 UTC
(In reply to comment #1)
Tobias,

Isn't the problem the following?

    parm.22.dim[0].lbound = 1;
    parm.22.dim[0].ubound = D.1616;
    parm.22.dim[0].stride = NON_LVALUE_EXPR <D.1622>;
    parm.22.data = (void *) &(*ifm.21)[0];
    parm.22.offset = NON_LVALUE_EXPR <D.1621>;
    D.1623 = _gfortran_internal_pack (&parm.22);  /**** void* result ****/
    D.1625 = mysize (D.1623); /**** mysize expects struct array1_integer(kind=4) & a   ****/
    D.1627 = MAX_EXPR <D.1625, 0> * 64;
    if (D.1627 < 0)
      {
        _gfortran_runtime_error (&"Attempt to allocate a negative amount of memory."[1]{lb: 1 sz: 1});
      }
    D.1628 = __builtin_malloc (MAX_EXPR <(integer(kind=8)) D.1627, 1>);
    if (D.1628 == 0B)
      {
        _gfortran_os_error (&"Memory allocation failed"[1]{lb: 1 sz: 1});
      }
    pstr.23 = (character(kind=1)[1:MAX_EXPR <D.1625, 0>] *) D.1628;
    p (pstr.23, MAX_EXPR <D.1625, 0>, D.1614, mysize);


Thus it's the internal_pack that does this in.

Paul
Comment 3 Paul Thomas 2008-11-08 17:50:56 UTC
(In reply to comment #2)
> (In reply to comment #1)

...and this comes about because gfc_apply_interface_mapping is failing to add the formal arguments to the new symbol used to evaluate expression for asz(y).  I cannot see why right now :-(

Paul
Comment 4 Paul Thomas 2008-11-14 19:00:42 UTC
A fix is regtesting right now.

Paul
Comment 5 Paul Thomas 2008-11-15 05:57:36 UTC
Created attachment 16680 [details]
A prototype patch

This fixes the problem but causes a couple of regressions - eg. mapping_1.f90

This clearly demonstrates that the replacement function needs a formal arglist to work correctly.

Paul
Comment 6 Paul Thomas 2008-11-15 17:27:37 UTC
Subject: Bug 37926

Author: pault
Date: Sat Nov 15 17:26:13 2008
New Revision: 141890

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141890
Log:
2008-11-15  Paul Thomas  <pault@gcc.gnu.org>

        PR fortran/37926
        * trans-expr.c (gfc_add_interface_mapping): Transfer the formal
	arglist and the always_explicit attribute if the dummy arg is a
	procedure.

2008-11-15  Paul Thomas  <pault@gcc.gnu.org>

        PR fortran/37926
        * gfortran.dg/dummy_procedure_3.f90: New test.

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

Comment 7 Paul Thomas 2008-11-16 12:02:07 UTC
Subject: Bug 37926

Author: pault
Date: Sun Nov 16 12:00:44 2008
New Revision: 141914

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=141914
Log:
2008-11-16  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/37926
	* trans-expr.c (gfc_free_interface_mapping): Null sym->formal
	(gfc_add_interface_mapping): Copy the pointer to the formal
	arglist, rather than using copy_formal_args.

Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c

Comment 8 Paul Thomas 2008-11-24 19:20:04 UTC
Subject: Bug 37926

Author: pault
Date: Mon Nov 24 19:18:39 2008
New Revision: 142171

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=142171
Log:
2008-11-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/37926
	* trans-expr.c (gfc_free_interface_mapping): Null sym->formal
	(gfc_add_interface_mapping): Copy the pointer to the formal
	arglist and set attr.always_explicit if this is a procedure.

2008-11-24  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/37926
	* gfortran.dg/dummy_procedure_3.f90: New test.

Added:
    branches/gcc-4_3-branch/gcc/testsuite/gfortran.dg/dummy_procedure_3.f90
Modified:
    branches/gcc-4_3-branch/gcc/fortran/ChangeLog
    branches/gcc-4_3-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_3-branch/gcc/testsuite/ChangeLog

Comment 9 Paul Thomas 2008-11-24 19:20:38 UTC
Fixed on trunk and 4.3.

Thanks for the report.

Paul