]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR fortran/46638 (Wrong result with TRANSFER from string to DT)
authorTobias Burnus <burnus@net-b.de>
Thu, 25 Nov 2010 08:04:46 +0000 (09:04 +0100)
committerTobias Burnus <burnus@gcc.gnu.org>
Thu, 25 Nov 2010 08:04:46 +0000 (09:04 +0100)
2010-11-25  Tobias Burnus  <burnus@net-b.de>

        PR fortran/46638
        * target-memory.c (gfc_interpret_derived): Correctly handle
        component offset.

2010-11-25  Tobias Burnus  <burnus@net-b.de>

        PR fortran/46638
        * gfortran.dg/transfer_simplify_10.f90: New.

From-SVN: r167138

gcc/fortran/ChangeLog
gcc/fortran/target-memory.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/transfer_simplify_10.f90 [new file with mode: 0644]

index 6e3a475b7e1a567a5b20fb180bf687b55f9417f9..6c064431a1f34a90ce0d6cb59b8af7007b213836 100644 (file)
@@ -1,3 +1,9 @@
+2010-11-25  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/46638
+       * target-memory.c (gfc_interpret_derived): Correctly handle
+       component offset.
+
 2010-11-13  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/45742
index dc10b53d926e7885812d3d56c59a84287954092c..baac1efd0c2eb2bf43232d9ad57b1a955159e783 100644 (file)
@@ -484,7 +484,16 @@ gfc_interpret_derived (unsigned char *buffer, size_t buffer_size, gfc_expr *resu
             }
        }
 
-      ptr = TREE_INT_CST_LOW (DECL_FIELD_OFFSET (cmp->backend_decl));
+      /* Calculate the offset, which consists of the the FIELD_OFFSET in
+        bytes, which appears in multiples of DECL_OFFSET_ALIGN-bit-sized,
+        and additional bits of FIELD_BIT_OFFSET. The code assumes that all
+        sizes of the components are multiples of BITS_PER_UNIT,
+        i.e. there are, e.g., no bit fields.  */
+
+      ptr = TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (cmp->backend_decl));
+      gcc_assert (ptr % 8 == 0);
+      ptr = ptr/8 + TREE_INT_CST_LOW (DECL_FIELD_OFFSET (cmp->backend_decl));
+
       gfc_target_interpret_expr (&buffer[ptr], buffer_size - ptr,
                                 tail->expr);
 
index 3aa0ead71c8ee67a7e814a0d786e9bb22565e41a..e5244fc17fc4c35bbb730f371fa2d89463d121d1 100644 (file)
@@ -1,3 +1,8 @@
+2010-11-25  Tobias Burnus  <burnus@net-b.de>
+
+       PR fortran/46638
+       * gfortran.dg/transfer_simplify_10.f90: New.
+
 2010-11-13  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/45742
diff --git a/gcc/testsuite/gfortran.dg/transfer_simplify_10.f90 b/gcc/testsuite/gfortran.dg/transfer_simplify_10.f90
new file mode 100644 (file)
index 0000000..d0c83b5
--- /dev/null
@@ -0,0 +1,28 @@
+! { dg-do run }
+!
+! PR fortran/46638
+!
+! Contributed by James Van Buskirk
+!
+program test5
+   use ISO_C_BINDING
+   implicit none
+   type, bind(C) :: CPUID_type
+      integer(C_INT32_T) eax
+      integer(C_INT32_T) ebx
+      integer(C_INT32_T) edx
+      integer(C_INT32_T) ecx
+      integer(C_INT32_T) bbb
+   end type CPUID_type
+   type(CPUID_TYPE) result
+  result = transfer(achar(10)//achar(0)//achar(0)//achar(0)//'GenuineIntel'//'abcd',result)
+
+  if (     int(z'0000000A') /= result%eax  &
+      .or. int(z'756E6547') /= result%ebx  &
+      .or. int(z'49656E69') /= result%edx  &
+      .or. int(z'6C65746E') /= result%ecx  &
+      .or. int(z'64636261') /= result%bbb) then
+    write(*,'(5(z8.8:1x))') result
+    call abort()
+  end if
+end program test5