Bug 47523 - Concatenation with deferred length character with lhs variable
Concatenation with deferred length character with lhs variable
Status: RESOLVED FIXED
Product: gcc
Classification: Unclassified
Component: fortran
4.6.0
: P3 normal
: ---
Assigned To: Paul Thomas
: wrong-code
Depends on:
Blocks: 45170
  Show dependency treegraph
 
Reported: 2011-01-28 20:34 UTC by Thomas Koenig
Modified: 2011-02-02 18:04 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-01-29 14:58:37


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Koenig 2011-01-28 20:34:21 UTC
Hi Paul,

sorry to be the first one to find a bug in your really cool
deferred length allocatable scalars.

Test case:

ig25@linux-fd1f:~/Krempel/Char-alloc> cat foo.f90
program main
  implicit none
  character(:), allocatable :: a, b
  a = 'a'
  print '(A)', a
  a = a // 'x'
  print '(A,A)',a
  print *,len(a)
end program main
ig25@linux-fd1f:~/Krempel/Char-alloc> gfortran foo.f90
ig25@linux-fd1f:~/Krempel/Char-alloc> ./a.out
a
a
           2

Output should be

a
ax
           2

The last line shows the length is correct, maybe it's just the
interaction with the library.  I will investigate a bit more.
Comment 1 Thomas Koenig 2011-01-28 20:58:49 UTC
Actually, it isn't a wrong length, the problem was an
invisible nul character in the output.

Look at this:

program main
  implicit none
  integer :: i
  character(:), allocatable :: a, b, c
  a = 'a'
  a = a // 'x'
  b = 'b'
  c = b // 'x'
  write (*,*) 'a is:'
  do i=1,len(a)
    write (*,*) ichar(a(i:i))
  end do

  write (*,*) 'c is:'
  do i=1,len(c)
     write (*,*) ichar(c(i:i))
  end do
end program main
ig25@linux-fd1f:~/Krempel/Char-alloc> gfortran bar.f90
ig25@linux-fd1f:~/Krempel/Char-alloc> ./a.out
 a is:
          97
           0
 c is:
          98
         120

The expression a = a // 'x' gets the wrong value for x.
Comment 2 Tobias Burnus 2011-01-28 21:04:40 UTC
I think I/O is OK - the issue is probably the same as PR 47519: Mishandling of intrinsic operations. Though, this case looks a bit different than the other PR.

void
concat_string (gfc_charlen_type destlen, CHARTYPE * dest,
               gfc_charlen_type len1, const CHARTYPE * s1,
               gfc_charlen_type len2, const CHARTYPE * s2)

But for   a = a // 'x'


        if (a != 0B) goto L.3;
        L.3:;
        a = (character(kind=1)[1:.a] *) __builtin_realloc ((void *) a, (<unnamed-unsigned:64>) (.a + 1));
        L.4:;
        .a = .a + 1;
        D.1536 = (.a + 1) * 64;
        D.1537 = (void * restrict) __builtin_malloc (MAX_EXPR <(<unnamed-unsigned:64>) D.1536, 1>);
        pstr.0 = (character(kind=1)[1:] *) D.1537;
        _gfortran_concat_string (.a + 1, pstr.0, .a, a, 1, &"x"[1]{lb: 1 sz: 1});

Thus, one first allocates "a", increments the length and then uses as "s1" argument to the intrinsic. That cannot work ...
Comment 3 Paul Thomas 2011-01-29 14:58:37 UTC
I have a patch cooking - thanks for the report Thomas!

Paul
Comment 4 Paul Thomas 2011-01-30 17:50:07 UTC
Author: pault
Date: Sun Jan 30 17:50:01 2011
New Revision: 169413

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169413
Log:
2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* gfortran.dg/allocatable_function_5.f90: New test not added by
	mistake on 2011-01-28.



Added:
    trunk/gcc/testsuite/gfortran.dg/allocatable_function_5.f90
    trunk/gcc/testsuite/gfortran.dg/realloc_on_assign_5.f03
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Paul Thomas 2011-01-30 17:56:22 UTC
Fixed on trunk.

Thanks, Thomas :-)

Cheers

Paul
Comment 6 Diego Novillo 2011-02-02 18:04:31 UTC
Author: dnovillo
Date: Wed Feb  2 18:04:21 2011
New Revision: 169697

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169697
Log:
2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

2011-01-30  Paul Thomas  <pault@gcc.gnu.org>

	PR fortran/47523
	* trans-expr.c (gfc_trans_assignment_1): If the rhs is an op
	expr and is assigned to a deferred character length scalar,
	make sure that the function is called before reallocation,
	so that the length is available. Include procedure pointer
	and procedure pointer component rhs as well.

	PR fortran/45170
	PR fortran/35810
	PR fortran/47350
	* gfortran.dg/allocatable_function_5.f90: New test not added by
	mistake on 2011-01-28.

Added:
    branches/google/integration/gcc/testsuite/gfortran.dg/allocatable_function_5.f90
    branches/google/integration/gcc/testsuite/gfortran.dg/realloc_on_assign_5.f03
Modified:
    branches/google/integration/gcc/fortran/ChangeLog
    branches/google/integration/gcc/fortran/trans-expr.c
    branches/google/integration/gcc/testsuite/ChangeLog