User account creation filtered due to spam.

Bug 50221 - Allocatable string length fails with array assignment
Summary: Allocatable string length fails with array assignment
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.6.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: wrong-code
: 70215 (view as bug list)
Depends on:
Blocks: 68241 45170
  Show dependency treegraph
 
Reported: 2011-08-28 16:08 UTC by Clive Page
Modified: 2016-03-13 08:15 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-06-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Clive Page 2011-08-28 16:08:16 UTC
The program below:

program testalloc
implicit none
character(:), allocatable, dimension(:) :: array
array = (/'xx', 'yy', 'zz'/)
print *, 'array=', array, len(array(1)), size(array)
end program

Should print out something like:
 array=xxyyzz           2           3
but with gfortran (v4.6.0) I get
 array=zzzzzz           2           3
Comment 1 Tobias Burnus 2011-08-29 07:32:18 UTC
Unfortunately, there are still some issues with deferred-length character strings - including arrays; see also bug 45170 comment 9.
Comment 2 Tobias Burnus 2012-05-12 12:10:33 UTC
The following program illustrates some of the problems:

a) If the comment lines are removed (i.e. a module is used), there is no valgrind failure and the result is correct. (Note: It requires the patch from PR 53329 with "ns" replaced by "sym->ns".)

b) The program (as is) shows no valgrind failure, but the assignment is wrong: "c3", "c3", "c3" instead of "a1", "b2", "c3".

c) If one removes the "save,", the result is as with (b) but valgrind shows many errors of the form:
  Conditional jump or move depends on uninitialised value(s)
    at 0x4C2C3A9: memcpy@@GLIBC_2.14
(The same failures one gets for the original program of comment 0.)


Looking at the dump for (b) - also in comparison with (a) -, I fail to see why one get's ["c1","c1","c1"] - the code looks correct ("S.0" goes from 1 to 3):

 __builtin_memcpy ((void *) &(*D.1881)[(S.0 + D.1885) + D.1882],
                   (void *) &const[S.0 + -1], (unsigned long) D.1887);

In principle, accessing the second argument wrongly should cause that problem. But that one looks okay. I wonder more about the left as
   (*D.1881)[...]
assumes that the compiler knows the size of one element - I am not sure that that works as ".str" is not yet the right value before the line:

    character(kind=1)[0:][1:.str] * restrict D.1881;


!module m
  character(len=:), save, allocatable :: str(:)
  character(len=2), parameter :: const(3) = ["a1", "b2", "c3"]
!end
!use m
call test()
if(allocated(str)) deallocate(str)
contains
subroutine test()
  call doit()
  print *, 'strlen=',len(str),' / array size =',size(str)
  print '(3a)', '>',str(1),'<'
  print '(3a)', '>',str(2),'<'
  print '(3a)', '>',str(3),'<'
end subroutine test
subroutine doit()
    str = const
end subroutine doit
end
Comment 3 Dominique d'Humieres 2013-06-16 14:31:38 UTC
Still present at revision 200128.
Comment 4 Arjen Markus 2015-05-15 13:17:32 UTC
I had a probably related failure with the following program using 4.9.2 under Cygwin. 

The program:

! chk_alloc_string.f90 --
!     Check if allocatable-length strings work in principle
!
program chk_alloc_string
    implicit none

    character(len=:), dimension(:), allocatable :: strings
    integer :: i

    allocate( character(10):: strings(1:3) )

    !strings = [ "A", "C", "ABCDE", "V" ]
    strings = [ character(len=4) :: "A", "C", "ABCDE", "V" ]

    write(*,*) len(strings(1)), size(strings)
    write(*,'(a)') strings
end program chk_alloc_string

The output:

           4           4
ACAV
CAV 
AV  
V    

where I expected:
           4           4
A
C
ABCD
V
Comment 5 Dominique d'Humieres 2015-11-06 15:45:15 UTC
Note that the output for comment 0 is

 array=xxyyzz           2           3

when compiled with 

Using built-in specs.
COLLECT_GCC=/opt/gcc/gcc6a-222042/bin/gfortran
COLLECT_LTO_WRAPPER=/opt/gcc/gcc6a-222042/bin/../libexec/gcc/x86_64-apple-darwin14.3.0/6.0.0/lto-wrapper
Target: x86_64-apple-darwin14.3.0
Configured with: ../_clean/configure --prefix=/opt/gcc/gcc6a --enable-languages=c,c++,fortran,ada,lto --with-gmp=/opt/mp-new --with-system-zlib --enable-checking=release --with-isl=/opt/mp-new --enable-lto --enable-plugin
Thread model: posix
gcc version 6.0.0 20150413 (experimental) [trunk revision 222042] (GCC) 

and

Using built-in specs.
COLLECT_GCC=/opt/gcc/gcc6p-227742/bin/gfortran
COLLECT_LTO_WRAPPER=/opt/gcc/gcc6p-227742/libexec/gcc/x86_64-apple-darwin14.5.0/6.0.0/lto-wrapper
Target: x86_64-apple-darwin14.5.0
Configured with: ../p_work/configure --prefix=/opt/gcc/gcc6p-227742 --enable-languages=c,c++,lto,fortran,ada,objc,obj-c++ --with-gmp=/opt/mp-new --with-system-zlib --enable-checking=release --with-isl=/opt/mp-new --enable-lto --enable-plugin --with-arch=core2 --with-cpu=core2
Thread model: posix
gcc version 6.0.0 20150914 (experimental) [trunk revision 227742] (GCC) 

I still get the wrong output 'array=zzzzzz' with

[Book15] f90/bug% /opt/gcc/gcc6p-226431/bin/gfortran -v
Using built-in specs.
COLLECT_GCC=/opt/gcc/gcc6p-226431/bin/gfortran
COLLECT_LTO_WRAPPER=/opt/gcc/gcc6p-226431/libexec/gcc/x86_64-apple-darwin14.4.0/6.0.0/lto-wrapper
Target: x86_64-apple-darwin14.4.0
Configured with: ../p_work/configure --prefix=/opt/gcc/gcc6p-226431 --enable-languages=c,c++,lto,fortran,ada,objc,obj-c++ --with-gmp=/opt/mp-new --with-system-zlib --enable-checking=release --with-isl=/opt/mp-new --enable-lto --enable-plugin --with-arch=core2 --with-cpu=core2
Thread model: posix
gcc version 6.0.0 20150731 (experimental) [trunk revision 226431] (GCC) 

However for all versions I have tested I get a wrong output (depending on the revision) for the test in comment 4.
Comment 6 Paul Thomas 2015-11-12 12:53:35 UTC
Since my recent patch fixes it, I had better take it!

Paul
Comment 7 Paul Thomas 2015-11-15 14:08:24 UTC
Author: pault
Date: Sun Nov 15 14:07:52 2015
New Revision: 230396

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

	PR fortran/50221
	PR fortran/68216
	PR fortran/63932
	PR fortran/66408
	* trans_array.c (gfc_conv_scalarized_array_ref): Pass the
	symbol decl for deferred character length array references.
	* trans-stmt.c (gfc_trans_allocate): Keep the string lengths
	to update deferred length character string lengths.
	* trans-types.c (gfc_get_dtype_rank_type); Use the string
	length of deferred character types for the dtype size.
	* trans.c (gfc_build_array_ref): For references to deferred
	character arrays, use the domain max value, if it is a variable
	to set the 'span' and use pointer arithmetic for acces to the
	element.
	(trans_code): Set gfc_current_locus for diagnostic purposes.

	PR fortran/67674
	* trans-expr.c (gfc_conv_procedure_call): Do not fix deferred
	string lengths of components.

	PR fortran/49954
	* resolve.c (deferred_op_assign): New function.
	(gfc_resolve_code): Call it.
	* trans-array.c (concat_str_length): New function.
	(gfc_alloc_allocatable_for_assignment): Jump directly to alloc/
	realloc blocks for deferred character length arrays because the
	string length might change, even if the shape is the same. Call
	concat_str_length to obtain the string length for concatenation
	since it is needed to compute the lhs string length.
	Set the descriptor dtype appropriately for the new string
	length.
	* trans-expr.c (gfc_trans_assignment_1): Use the rse string
	length for all characters, other than deferred types. For
	concatenation operators, push the rse.pre block to the inner
	most loop so that the temporary pointer and the assignments
	are properly placed.

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

	PR fortran/50221
	* gfortran.dg/deferred_character_1.f90: New test.
	* gfortran.dg/deferred_character_4.f90: New test for comment
	#4 of the PR.

	PR fortran/68216
	* gfortran.dg/deferred_character_2.f90: New test.

	PR fortran/67674
	* gfortran.dg/deferred_character_3.f90: New test.

	PR fortran/63932
	* gfortran.dg/deferred_character_5.f90: New test.

	PR fortran/66408
	* gfortran.dg/deferred_character_6.f90: New test.

	PR fortran/49954
	* gfortran.dg/deferred_character_7.f90: New test.

Added:
    trunk/gcc/testsuite/gfortran.dg/deferred_character_1.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_2.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_3.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_4.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_5.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_6.f90
    trunk/gcc/testsuite/gfortran.dg/deferred_character_7.f90
Modified:
    trunk/gcc/fortran/ChangeLog
    trunk/gcc/fortran/resolve.c
    trunk/gcc/fortran/trans-array.c
    trunk/gcc/fortran/trans-expr.c
    trunk/gcc/fortran/trans-stmt.c
    trunk/gcc/fortran/trans.c
    trunk/gcc/testsuite/ChangeLog
Comment 8 Paul Thomas 2016-01-10 18:07:15 UTC
Author: pault
Date: Sun Jan 10 18:06:43 2016
New Revision: 232203

URL: https://gcc.gnu.org/viewcvs?rev=232203&root=gcc&view=rev
Log:
2016-01-10  Paul Thomas  <pault@gcc.gnu.org>

	Backport from mainline.
	PR fortran/50221
	PR fortran/68216
	PR fortran/63932
	PR fortran/66408
	* trans_array.c (gfc_conv_scalarized_array_ref): Pass the
	symbol decl for deferred character length array references.
	* trans-stmt.c (gfc_trans_allocate): Keep the string lengths
	to update deferred length character string lengths.
	* trans-types.c (gfc_get_dtype_rank_type); Use the string
	length of deferred character types for the dtype size.
	* trans.c (gfc_build_array_ref): For references to deferred
	character arrays, use the domain max value, if it is a variable
	to set the 'span' and use pointer arithmetic for acces to the
	element.
	(trans_code): Set gfc_current_locus for diagnostic purposes.

	Backport from mainline.
	PR fortran/67674
	* trans-expr.c (gfc_conv_procedure_call): Do not fix deferred
	string lengths of components.

	Backport from mainline.
	PR fortran/49954
	* resolve.c (deferred_op_assign): New function.
	(gfc_resolve_code): Call it.
	* trans-array.c (concat_str_length): New function.
	(gfc_alloc_allocatable_for_assignment): Jump directly to alloc/
	realloc blocks for deferred character length arrays because the
	string length might change, even if the shape is the same. Call
	concat_str_length to obtain the string length for concatenation
	since it is needed to compute the lhs string length.
	Set the descriptor dtype appropriately for the new string
	length.
	* trans-expr.c (gfc_trans_assignment_1): Fix the rse string
	length for all characters, other than deferred types. For
	concatenation operators, push the rse.pre block to the inner
	most loop so that the temporary pointer and the assignments
	are properly placed.

	Backport from mainline.
	PR fortran/67779
	* trans_array.c (gfc_conv_scalarized_array_ref): Add missing
	se->use_offset from condition for calculation of 'base'.

2015-01-10  Paul Thomas  <pault@gcc.gnu.org>

	Backport from mainline.
	PR fortran/50221
	* gfortran.dg/deferred_character_1.f90: New test.
	* gfortran.dg/deferred_character_4.f90: New test for comment
	#4 of the PR.

	Backport from mainline.
	PR fortran/68216
	* gfortran.dg/deferred_character_2.f90: New test.

	Backport from mainline.
	PR fortran/67674
	* gfortran.dg/deferred_character_3.f90: New test.

	Backport from mainline.
	PR fortran/63932
	* gfortran.dg/deferred_character_5.f90: New test.

	Backport from mainline.
	PR fortran/66408
	* gfortran.dg/deferred_character_6.f90: New test.

	Backport from mainline.
	PR fortran/49954
	* gfortran.dg/deferred_character_7.f90: New test.

	Backport from mainline.
	PR fortran/67779
	* gfortran.dg/actual_array_offset_1: New test.

Added:
    branches/gcc-5-branch/gcc/fortran/ChangeLog-2015
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/actual_array_offset_1.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_1.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_2.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_3.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_4.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_5.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_6.f90
    branches/gcc-5-branch/gcc/testsuite/gfortran.dg/deferred_character_7.f90
Modified:
    branches/gcc-5-branch/gcc/fortran/ChangeLog
    branches/gcc-5-branch/gcc/fortran/resolve.c
    branches/gcc-5-branch/gcc/fortran/trans-array.c
    branches/gcc-5-branch/gcc/fortran/trans-expr.c
    branches/gcc-5-branch/gcc/fortran/trans-stmt.c
    branches/gcc-5-branch/gcc/fortran/trans-types.c
    branches/gcc-5-branch/gcc/fortran/trans.c
    branches/gcc-5-branch/gcc/testsuite/ChangeLog
Comment 9 Paul Thomas 2016-01-10 18:15:26 UTC
Closed on trunk and 5-branch.

Thanks for the report.

Paul
Comment 10 Dominique d'Humieres 2016-03-13 08:15:24 UTC
*** Bug 70215 has been marked as a duplicate of this bug. ***