Bug 29315 - error passing an array derived from type element
Summary: error passing an array derived from type element
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: fortran (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: ---
Assignee: Paul Thomas
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2006-10-02 02:41 UTC by Stephen Jeffrey
Modified: 2006-11-12 07:44 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-10-27 14:37:47


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stephen Jeffrey 2006-10-02 02:41:45 UTC
Could you please examine the code below. 

The code constructs an array of structures, where the structure contains an array of integers. The code then attempts to pass the first element of each structure's array into an array in a subroutine - this step fails. It appears as though the memory locations being accessed to generate the temporary array in the subroutine has an incorrect stride. The stride appears to be 1, instead of the size of the structure.

The code appears to run correctly when compiled with SGI and Cray compilers.

Results are:
------------
Results when compiled with gfc compiler:
Original:                     1          11          21
Original:                     2          12          22
Original:                     3          13          23
Original:                     4          14          24
Original:                     5          15          25
 
Added 100 to a(1):          101         102         103
Added 100 to a(1):          104         105          22
Added 100 to a(1):            3          13          23
Added 100 to a(1):            4          14          24
Added 100 to a(1):            5          15          25
 
 
 
Results when compiled with SGI compiler, or Cray compiler:
Original:            1,  11,  21
 Original:           2,  12,  22
 Original:           3,  13,  23
 Original:           4,  14,  24
 Original:           5,  15,  25
  
 Added 100 to a(1):  101,  11,  21
 Added 100 to a(1):  102,  12,  22
 Added 100 to a(1):  103,  13,  23
 Added 100 to a(1):  104,  14,  24
 Added 100 to a(1):  105,  15,  25

Code is:
--------

program  test_f90

    integer, parameter :: N = 5

    type test_type
        integer a(3)
    end type

    type (test_type) s(N)
    integer i

!   "s" is an array of structures,where the structure contains an array of length 3
    do i=1, N
        s(i)%a(1) = i
        s(i)%a(2) = i + 10
        s(i)%a(3) = i + 20
    enddo

!   "s" is initialised as follows:  s(1)%a(1) =   1, s(1)%a(2) = 11,  s(1)%a(3) = 21
!                                   s(2)%a(1) =   2, s(2)%a(2) = 12,  s(2)%a(3) = 22
!                                   s(3)%a(1) =   3, s(3)%a(2) = 13,  s(3)%a(3) = 23
!                                   s(4)%a(1) =   4, s(4)%a(2) = 14,  s(4)%a(3) = 24
!                                   s(5)%a(1) =   5, s(5)%a(2) = 15,  s(5)%a(3) = 25


    do i=1, N
    write(*, *) 'Original:          ', s(i)%a(1), s(i)%a(2), s(i)%a(3)
    enddo
    write(*, *) ' '

!   Add an offset to: s(1)%a(1), s(2)%a(1), s(3)%a(1), s(4)%a(1), s(5)%a(1)
    call test_sub(s%a(1), 100)

!   "s" should now contain:         s(1)%a(1) = 101, s(1)%a(2) = 11,  s(1)%a(3) = 21
!                                   s(2)%a(1) = 102, s(2)%a(2) = 12,  s(2)%a(3) = 22
!                                   s(3)%a(1) = 103, s(3)%a(2) = 13,  s(3)%a(3) = 23
!                                   s(4)%a(1) = 104, s(4)%a(2) = 14,  s(4)%a(3) = 24
!                                   s(5)%a(1) = 105, s(5)%a(2) = 15,  s(5)%a(3) = 25

    do i=1, N
    write(*, *) 'Added 100 to a(1): ', s(i)%a(1), s(i)%a(2), s(i)%a(3)
    enddo

contains

subroutine test_sub(array, offset)
    integer array(:), offset
    integer i

    do i=1, N
        array(i) = i + offset
    enddo
end subroutine

end program
Comment 1 Andrew Pinski 2006-10-02 02:53:33 UTC
I know I have seen a bug like this before.
Comment 2 Andrew Pinski 2006-10-02 03:07:51 UTC
Confirmed, we don't set the stride correctly as far as I can tell.
Comment 3 Paul Thomas 2006-10-02 08:09:03 UTC
(In reply to comment #2)
> Confirmed, we don't set the stride correctly as far as I can tell.

This comes about because of the admitted kludge in the mechanism for passing components of derived type arrays. At line 1588 in trans-exp.c, you will find the comment:

/* Returns a reference to a temporary array into which a component of
   an actual argument derived type array is copied and then returned
   after the function call.
   TODO Get rid of this kludge, when array descriptors are capable of
   handling aliased arrays.  */

Maybe the time has come for byte size strides, although it will be a horrific job to implement.

Paul

Comment 4 Paul Thomas 2006-10-27 14:37:47 UTC
I am sorry but I realised on looking at this again that the stride has nothing to do with this one - the patch below regtests but has not been checked for correct-in-all-cases logic.  Since the original was incorrect, give me a couple more days to get home and give this some clear thought... or what goes for clear thought.

Paul


Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c    (revision 117860)
--- gcc/fortran/trans-expr.c    (working copy)
*************** is_aliased_array (gfc_expr * e)
*** 1840,1846 ****
        if (ref->type == REF_ARRAY)
        seen_array = true;

!       if (ref->next == NULL
            && ref->type != REF_ARRAY)
        return seen_array;
      }
--- 1845,1851 ----
        if (ref->type == REF_ARRAY)
        seen_array = true;

!       if (seen_array
            && ref->type != REF_ARRAY)
        return seen_array;
      }
Comment 5 patchapp@dberlin.org 2006-11-09 22:40:47 UTC
Subject: Bug number PR29315

A patch for this bug has been added to the patch tracker.
The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-11/msg00582.html
Comment 6 Paul Thomas 2006-11-10 17:22:10 UTC
Subject: Bug 29315

Author: pault
Date: Fri Nov 10 17:21:57 2006
New Revision: 118659

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

	PR fortran/29315
	* trans-expr.c (is_aliased_array): Treat correctly the case where the
	component is itself and array or array reference.


2006-11-10 Paul Thomas <pault@gcc.gnu.org>

	PR fortran/29315
	* gfortran.dg/aliasing_dummy_4.f90: New test.

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

Comment 7 Paul Thomas 2006-11-12 07:40:44 UTC
Subject: Bug 29315

Author: pault
Date: Sun Nov 12 07:40:26 2006
New Revision: 118719

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

	PR fortran/29699
	* trans-array.c (structure_alloc_comps): Detect pointers to
	arrays and use indirect reference to declaration.
	* resolve.c (resolve_fl_variable): Tidy up condition.
	(resolve_symbol): The same and only add initialization code if
	the symbol is referenced.
	* trans-decl.c (gfc_trans_deferred_vars): Call gfc_trans_
	deferred_array before gfc_trans_auto_array_allocation.

	PR fortran/21730
	* symbol.c (check_done): Remove.
	(gfc_add_attribute): Remove reference to check_done and remove
	the argument attr_intent.
	(gfc_add_allocatable, gfc_add_dimension, gfc_add_external,
	gfc_add_intrinsic, gfc_add_optional, gfc_add_pointer,
	gfc_add_cray_pointer, gfc_add_cray_pointee, gfc_add_result,
	gfc_add_target, gfc_add_in_common, gfc_add_elemental,
	gfc_add_pure, gfc_add_recursive, gfc_add_procedure,
	gfc_add_type): Remove references to check_done.
	* decl.c (attr_decl1): Eliminate third argument in call to
	gfc_add_attribute.
	* gfortran.h : Change prototype for gfc_add_attribute.

	PR fortran/29431
	* trans-array.c    (get_array_ctor_strlen): If we fall through to
	default, use a constant character length if it is available.

	PR fortran/29758
	* check.c (gfc_check_reshape): Check that there are enough
	elements in the source array as to be able to fill an array
	defined by shape, when pad is absent.

	PR fortran/29315
	* trans-expr.c (is_aliased_array): Treat correctly the case where the
	component is itself and array or array reference.


2006-11-12 Paul Thomas <pault@gcc.gnu.org>

	PR fortran/29699
	* gfortran.dg/alloc_comp_auto_array_1.f90: New test.

	PR fortran/21730
	* gfortran.dg/change_symbol_attributes_1.f90: New test.

	PR fortran/29431
	* gfortran.dg/array_constructor_13.f90: New test.

	PR fortran/29758
	* gfortran.dg/reshape_source_size_1.f90: New test.

	PR fortran/29315
	* gfortran.dg/aliasing_dummy_4.f90: New test.

Added:
    branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/aliasing_dummy_4.f90
    branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/alloc_comp_auto_array_1.f90
    branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/array_constructor_13.f90
    branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/change_symbol_attributes_1.f90
    branches/gcc-4_2-branch/gcc/testsuite/gfortran.dg/reshape_source_size_1.f90
Modified:
    branches/gcc-4_2-branch/gcc/fortran/ChangeLog
    branches/gcc-4_2-branch/gcc/fortran/check.c
    branches/gcc-4_2-branch/gcc/fortran/decl.c
    branches/gcc-4_2-branch/gcc/fortran/gfortran.h
    branches/gcc-4_2-branch/gcc/fortran/resolve.c
    branches/gcc-4_2-branch/gcc/fortran/symbol.c
    branches/gcc-4_2-branch/gcc/fortran/trans-array.c
    branches/gcc-4_2-branch/gcc/fortran/trans-decl.c
    branches/gcc-4_2-branch/gcc/fortran/trans-expr.c
    branches/gcc-4_2-branch/gcc/testsuite/ChangeLog

Comment 8 Paul Thomas 2006-11-12 07:44:03 UTC
Fixed on trunk and 4.2. 4.1 will follow next weekend.

Paul