This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH/RFA] PR gdb/648


This is a fix for a long-standing bug with multi-dimensional arrays in
fortran.  When printing individual elements of an array,
evaluate_subexp_standard understood the dimensions of the array to be in
the opposite order to that of the whatis or entire array printing.  This
led to bug 648, which was present for G77 compiled code, but the problem
was reversed for commercial compilers such as Intel or Portland.

G77 puts things in row-major order, as far as I can ascertain all other
fortran compilers do column major.  This is handled in the dwarf2read
change, and now column major array types are reversed during the reading
to fit with GDB's struct type.

2004-08-06  David Lecomber  <dsl@sources.redhat.com>
 
        Fix PR gdb/648
        * dwarf2read.c (read_array_type): Handle column major arrays
        correctly.  Assume column major for Fortran except with G77
        compiler.
        * eval.c (evaluate_subexp_standard): Assume Fortran arrays are
        oriented large to small in type structure.


Attached is a test program and test script, should return true for all 
comparisons..  

I'm sure there'll be some comments, so please feel free to suggest some
reformatting!

David.

Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.156
diff -c -p -r1.156 dwarf2read.c
*** gdb/dwarf2read.c	6 Jul 2004 19:29:30 -0000	1.156
--- gdb/dwarf2read.c	28 Jul 2004 13:03:05 -0000
*************** read_array_type (struct die_info *die, s
*** 3718,3726 ****
  
    /* Dwarf2 dimensions are output from left to right, create the
       necessary array types in backwards order.  */
    type = element_type;
!   while (ndim-- > 0)
!     type = create_array_type (NULL, type, range_types[ndim]);
  
    /* Understand Dwarf2 support for vector types (like they occur on
       the PowerPC w/ AltiVec).  Gcc just adds another attribute to the
--- 3720,3751 ----
  
    /* Dwarf2 dimensions are output from left to right, create the
       necessary array types in backwards order.  */
+ 
+   /* Take account of array ordering, if possible.  */
    type = element_type;
! 
!   attr = dwarf2_attr (die, DW_AT_ordering, cu);
! 
!   /* Trust this attribute if present.  If not, assume col-major for FORTRAN
!      unless the compiler is GNU F77 which puts things the opposite way to the
!      dwarf2 spec.  
! 
!      FIXME: dsl/2004-07-20: If G77 is ever fixed by checking version string of
!      producer.
!    */
!   if ((attr && (DW_SND(attr) == DW_ORD_col_major))
!       || (!attr && ( cu->language == language_fortran && 
! 		     ( !cu->producer || !strstr(cu->producer, "GNU F77" )))))
!     {
!       int i = 0;
!       while (i < ndim) 
! 	type = create_array_type (NULL, type, range_types[i++]);
!     }
!   else 
!     {
!       while (ndim-- > 0)
! 	type = create_array_type (NULL, type, range_types[ndim]);
!     }
  
    /* Understand Dwarf2 support for vector types (like they occur on
       the PowerPC w/ AltiVec).  Gcc just adds another attribute to the
Index: gdb/eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.41
diff -c -p -r1.41 eval.c
*** gdb/eval.c	8 Apr 2004 21:18:12 -0000	1.41
--- gdb/eval.c	28 Jul 2004 13:03:07 -0000
*************** evaluate_subexp_standard (struct type *e
*** 1610,1618 ****
  
      multi_f77_subscript:
        {
! 	int subscript_array[MAX_FORTRAN_DIMS + 1];	/* 1-based array of 
! 							   subscripts, max == 7 */
! 	int array_size_array[MAX_FORTRAN_DIMS + 1];
  	int ndimensions = 1, i;
  	struct type *tmp_type;
  	int offset_item;	/* The array offset where the item lives */
--- 1610,1617 ----
  
      multi_f77_subscript:
        {
! 	int subscript_array[MAX_FORTRAN_DIMS];
! 	int array_size_array[MAX_FORTRAN_DIMS];
  	int ndimensions = 1, i;
  	struct type *tmp_type;
  	int offset_item;	/* The array offset where the item lives */
*************** evaluate_subexp_standard (struct type *e
*** 1630,1636 ****
  	   let us actually find out where this element exists in the array. */
  
  	offset_item = 0;
! 	for (i = 1; i <= nargs; i++)
  	  {
  	    /* Evaluate each subscript, It must be a legal integer in F77 */
  	    arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
--- 1629,1636 ----
  	   let us actually find out where this element exists in the array. */
  
  	offset_item = 0;
! 	/* Take array indices left to right */
! 	for (i = 0; i < nargs; i++)
  	  {
  	    /* Evaluate each subscript, It must be a legal integer in F77 */
  	    arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
*************** evaluate_subexp_standard (struct type *e
*** 1638,1644 ****
--- 1638,1648 ----
  	    /* Fill in the subscript and array size arrays */
  
  	    subscript_array[i] = value_as_long (arg2);
+ 	  }
  
+ 	/* Internal type of array is arranged right to left */
+ 	for (i = 0; i < nargs; i++)
+ 	  {
  	    retcode = f77_get_dynamic_upperbound (tmp_type, &upper);
  	    if (retcode == BOUND_FETCH_ERROR)
  	      error ("Cannot obtain dynamic upper bound");
*************** evaluate_subexp_standard (struct type *e
*** 1647,1657 ****
  	    if (retcode == BOUND_FETCH_ERROR)
  	      error ("Cannot obtain dynamic lower bound");
  
! 	    array_size_array[i] = upper - lower + 1;
  
  	    /* Zero-normalize subscripts so that offsetting will work. */
  
! 	    subscript_array[i] -= lower;
  
  	    /* If we are at the bottom of a multidimensional 
  	       array type then keep a ptr to the last ARRAY
--- 1651,1661 ----
  	    if (retcode == BOUND_FETCH_ERROR)
  	      error ("Cannot obtain dynamic lower bound");
  
! 	    array_size_array[nargs - i - 1] = upper - lower + 1;
  
  	    /* Zero-normalize subscripts so that offsetting will work. */
  
! 	    subscript_array[nargs - i - 1] -= lower;
  
  	    /* If we are at the bottom of a multidimensional 
  	       array type then keep a ptr to the last ARRAY
*************** evaluate_subexp_standard (struct type *e
*** 1661,1677 ****
  	       of base element type that we apply a simple 
  	       offset to. */
  
! 	    if (i < nargs)
  	      tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type));
  	  }
  
  	/* Now let us calculate the offset for this item */
  
! 	offset_item = subscript_array[ndimensions];
  
! 	for (i = ndimensions - 1; i >= 1; i--)
  	  offset_item =
! 	    array_size_array[i] * offset_item + subscript_array[i];
  
  	/* Construct a value node with the value of the offset */
  
--- 1665,1681 ----
  	       of base element type that we apply a simple 
  	       offset to. */
  
! 	    if (i < nargs - 1)
  	      tmp_type = check_typedef (TYPE_TARGET_TYPE (tmp_type));
  	  }
  
  	/* Now let us calculate the offset for this item */
  
! 	offset_item = subscript_array[ndimensions - 1];
  
! 	for (i = ndimensions - 1; i > 0; --i)
  	  offset_item =
! 	    array_size_array[i - 1] * offset_item + subscript_array[i - 1];
  
  	/* Construct a value node with the value of the offset */
  

Attachment: arrays.gdb
Description: Text document

      program first


      INTEGER X,Y,Z
      INTEGER i, j, k, l
      INTEGER onedi(10)
      INTEGER twodi(20,10)
      INTEGER threedi(3, 5, 7)
      INTEGER fourdi(4, 5, 7, 11)

      REAL*4 onedf(10)
      REAL*4 twodf(20,10)
      REAL*4 threedf(3, 5, 7)
      REAL*4 fourdf(4, 5, 7, 11)


      DO i=1,10
         onedi(i) = i
      ENDDO

      DO i=1,20
         DO j=1,10
            twodi(i,j) = i * j
         ENDDO
      ENDDO

      DO i=1,3
         DO j=1,5
            DO k=1,7
               threedi(i,j,k) = i * j + k
            ENDDO
         ENDDO
      ENDDO

      DO i=1,3
         DO j=1,5
            DO k=1,7
               DO m=1,11
                  fourdi(i,j,k,m) = i * j + k * m
               ENDDO
            ENDDO
         ENDDO
      ENDDO
      

      call oneif(onedi)
      call twoif(twodi)
      call threeif(threedi)
      call fourif(fourdi)






      DO i=1,10
         onedf(i) = i
      ENDDO

      DO i=1,20
         DO j=1,10
            twodf(i,j) = i * j
         ENDDO
      ENDDO

      DO i=1,3
         DO j=1,5
            DO k=1,7
               threedf(i,j,k) = i * j + k
            ENDDO
         ENDDO
      ENDDO

      DO i=1,3
         DO j=1,5
            DO k=1,7
               DO m=1,11
                  fourdf(i,j,k,m) = i * j + k * m
               ENDDO
            ENDDO
         ENDDO
      ENDDO
      

      call oneff(onedf)
      call twoff(twodf)
      call threeff(threedf)
      call fourff(fourdf)

      call known(fourdf, m)

      END


      SUBROUTINE oneif (array1)
      INTEGER array1(*)
      array1(1) = 1
      RETURN
      END

      SUBROUTINE twoif (array2)
      INTEGER array2(20, *)
      array2(1,1) = 11
      RETURN
      END


      SUBROUTINE threeif (array3)
      INTEGER array3(3, 5, *)
      array3(1,1,1) = 111
      RETURN
      END

      SUBROUTINE fourif (array4)
      INTEGER array4(4, 5, 7, *)
      array4(1,1,1,1) = 1111
      RETURN
      END 

      SUBROUTINE oneff (array1)
      REAL*4 array1(*)
      array1(1) = 1
      RETURN
      END


      SUBROUTINE twoff (array2)
      REAL*4 array2(20, *)
      array2(1,1) = 11
      RETURN
      END

      SUBROUTINE threeff (array3)
      REAL*4 array3(3, 5, *)
      array3(1,1,1) = 111
      RETURN
      END

      SUBROUTINE fourff (array4)
      REAL*4 array4(4, 5, 7, *)
      array4(1,1,1,1) = 1111
      RETURN
      END 

      SUBROUTINE known (array4, i)
      INTEGER i
      REAL*4 array4(4, 5, 7, i)
      array4(1,1,1,1) = 1111
      RETURN
      END 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]