diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 3fb70e0c12e63c70c02b422fd33891d4bfd12908..e836c0af382bf1be146a3fb7a86c9e33ddf4728e 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,9 @@
+2012-01-31  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/52012
+	* trans-expr.c (fcncall_realloc_result): Correct calculation of
+	result offset.
+
 2012-01-29  Janne Blomqvist  <jb@gcc.gnu.org>
 
 	* module.c (pointer_info): Make true_name and module pointers
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 7543149e32c6c01347231f116ab21e52565935e1..657b4f4fd5a974a327380eafe03fbb9b56891147 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -6310,16 +6310,11 @@ fcncall_realloc_result (gfc_se *se, int rank)
   gfc_add_modify (&se->post, desc, res_desc);
 
   offset = gfc_index_zero_node;
-  tmp = gfc_index_one_node;
-  /* Now reset the bounds from zero based to unity based.  */
+
+  /* Now reset the bounds from zero based to unity based and set the
+     offset accordingly.  */
   for (n = 0 ; n < rank; n++)
     {
-      /* Accumulate the offset.  */
-      offset = fold_build2_loc (input_location, MINUS_EXPR,
-				gfc_array_index_type,
-				offset, tmp);
-      /* Now do the bounds.  */
-      gfc_conv_descriptor_offset_set (&se->post, desc, tmp);
       tmp = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]);
       tmp = fold_build2_loc (input_location, PLUS_EXPR,
 			     gfc_array_index_type,
@@ -6330,15 +6325,16 @@ fcncall_realloc_result (gfc_se *se, int rank)
       gfc_conv_descriptor_ubound_set (&se->post, desc,
 				      gfc_rank_cst[n], tmp);
 
-      /* The extent for the next contribution to offset.  */
-      tmp = fold_build2_loc (input_location, MINUS_EXPR,
-			     gfc_array_index_type,
-			     gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[n]),
-			     gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]));
-      tmp = fold_build2_loc (input_location, PLUS_EXPR,
-			     gfc_array_index_type,
-			     tmp, gfc_index_one_node);
+      /* Accumulate the offset.  Since all lbounds are unity, offset
+	 is just minus the sum of the strides.  */
+      tmp = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[n]);
+      offset = fold_build2_loc (input_location, MINUS_EXPR,
+				gfc_array_index_type,
+				offset, tmp);
+      offset = gfc_evaluate_now (offset, &se->post);
+
     }
+
   gfc_conv_descriptor_offset_set (&se->post, desc, offset);
 }
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 77c86391983371293eaf84cd2cd8e6a3aa13eb53..ae4175f3482736d83666b7b70ba258910eda8be1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-31  Paul Thomas  <pault@gcc.gnu.org>
+
+	PR fortran/52012
+	* gfortran.dg/realloc_on_assign_10.f90: New test.
+
 2012-01-31  Richard Guenther  <rguenther@suse.de>
 
 	PR tree-optimization/51528
diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_10.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_10.f90
new file mode 100644
index 0000000000000000000000000000000000000000..787a56ae9e9ae30ba1be924a74893a9f80a6d019
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_10.f90
@@ -0,0 +1,18 @@
+! { dg-do run }
+! PR52012 - with realloc_lhs active(ie. default condition) the
+! offset was wrongly calculated for a, after assignment.
+!
+! Reported by Reinhold Bader and Tobias Burnus  <burnus@gcc.gnu.org>
+! 
+program gf
+  implicit none
+  real, allocatable :: a(:,:,:)
+  real, parameter :: zero = 0.0, one = 1.0
+  real :: b(3,4,5) = zero
+  b(1,2,3) = one
+  allocate (a(size (b, 3), size (b, 2), size (b, 1)))
+  a = reshape (b, shape (a), order = [3, 2, 1])
+  if (any (a(:, 2, 1) .ne. [zero, zero, one, zero, zero])) call abort
+  if (a(3, 2, 1) /= one) call abort()
+  if (sum (abs (a)) /= one) call abort()
+end program