Index: gcc/fortran/ChangeLog.fortran-dev
===================================================================
--- gcc/fortran/ChangeLog.fortran-dev	(Revision 185103)
+++ gcc/fortran/ChangeLog.fortran-dev	(Arbeitskopie)
@@ -1,3 +1,14 @@
+2012-03-10  Tobias Burnus  <burnus@net-b.de>
+
+	* trans-array.c (CAF_TOKEN_FIELD): Set to the correct value.
+	(gfc_conv_descriptor_ubound_get, gfc_conv_descriptor_ubound_set):
+	Remove bogus byte-size handling, correctly handle lower bounds
+	which don't start with unity.
+	(gfc_conv_shift_descriptor_lbound): Reorder to make sure that
+	lbound comes before ubound.
+	* trans-expr.c (gfc_conv_subref_array_arg,
+	gfc_trans_alloc_subarray_assign): Ditto.
+
 2010-09-01  Paul Thomas  <pault@gcc.gnu.org>
 
 	* trans-array.c : Define and subsequently undefine descriptor
Index: gcc/fortran/trans-array.c
===================================================================
--- gcc/fortran/trans-array.c	(Revision 185103)
+++ gcc/fortran/trans-array.c	(Arbeitskopie)
@@ -130,7 +130,7 @@ gfc_array_dataptr_type (tree desc)
 #define DTYPE_FIELD 2
 #define SIZE_FIELD 3
 #define DIMENSION_FIELD 4
-#define CAF_TOKEN_FIELD 4
+#define CAF_TOKEN_FIELD 5
 
 #define STRIDE_SUBFIELD 0
 #define LBOUND_SUBFIELD 1
@@ -472,16 +472,13 @@ gfc_conv_descriptor_ubound (tree desc, tree dim)
 tree
 gfc_conv_descriptor_ubound_get (tree desc, tree dim)
 {
-  tree cond, size;
-  tree tmp = gfc_get_element_type (TREE_TYPE (desc));
-  size = size_in_bytes (tmp);
-  size = fold_convert (gfc_array_index_type, size);
-  tmp = fold_build2_loc (input_location, FLOOR_DIV_EXPR, gfc_array_index_type,
-			 gfc_conv_descriptor_extent_get (desc, dim), size);
-  cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, size,
-			  gfc_index_zero_node);
-  tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond,
-			 gfc_index_zero_node, tmp);
+  tree lb = gfc_conv_descriptor_lbound (desc, dim);
+  tree tmp = gfc_conv_descriptor_extent_get (desc, dim);
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+                         fold_convert (gfc_array_index_type, lb),
+                         fold_convert (gfc_array_index_type, tmp));
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+			 tmp, gfc_index_one_node);
   return tmp;
 }
 
@@ -492,11 +489,12 @@ gfc_conv_descriptor_ubound_set (stmtblock_t *block
   tree tmp;
   tree t = gfc_conv_descriptor_ubound (desc, dim);
   gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value));
-  tmp = gfc_get_element_type (TREE_TYPE (desc));
-  tmp = size_in_bytes (tmp);
-  tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
-			 fold_convert (TREE_TYPE (t), value),
+  tmp =  gfc_conv_descriptor_lbound (desc, dim);
+  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
+			 fold_convert (TREE_TYPE (t), t),
 			 fold_convert (TREE_TYPE (t), tmp));
+  tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+			 tmp, gfc_index_one_node);
   gfc_conv_descriptor_extent_set (block, desc, dim, tmp);
 }
 
@@ -542,19 +540,20 @@ gfc_conv_shift_descriptor_lbound (stmtblock_t* blo
   diff = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
 			  new_lbound, lbound);
 
-  /* Shift ubound and offset accordingly.  This has to be done before
-     updating the lbound, as they depend on the lbound expression!  */
-  ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
-			    ubound, diff);
-  gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
   offs_diff = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
 			       diff, stride);
   offs = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
 			  offs, offs_diff);
   gfc_conv_descriptor_offset_set (block, desc, offs);
 
-  /* Finally set lbound to value we want.  */
+  /* Set lbound to value we want.  */
   gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[dim], new_lbound);
+
+  /* Update ubound. As it uses internally lbound + extend, it has to be after
+     the lbound expression!  */
+  ubound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
+			    ubound, diff);
+  gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound);
 }
 
 
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c	(Revision 185103)
+++ gcc/fortran/trans-expr.c	(Arbeitskopie)
@@ -3153,14 +3153,14 @@ gfc_conv_subref_array_arg (gfc_se * parmse, gfc_ex
 	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
 				 gfc_array_index_type, tmp,
 				 gfc_index_one_node);
+	  gfc_conv_descriptor_lbound_set (&parmse->pre,
+					  parmse->expr,
+					  gfc_rank_cst[n],
+					  gfc_index_one_node);
 	  gfc_conv_descriptor_ubound_set (&parmse->pre,
 					  parmse->expr,
 					  gfc_rank_cst[n],
 					  tmp);
-	  gfc_conv_descriptor_lbound_set (&parmse->pre,
-					  parmse->expr,
-					  gfc_rank_cst[n],
-					  gfc_index_one_node);
 	  size = gfc_evaluate_now (size, &parmse->pre);
 	  offset = fold_build2_loc (input_location, MINUS_EXPR,
 				    gfc_array_index_type,
@@ -5186,10 +5186,10 @@ gfc_trans_alloc_subarray_assign (tree dest, gfc_co
 		tmp, gfc_conv_descriptor_lbound_get (dest, gfc_rank_cst[n]));
       tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
 			     span, lbound);
+      gfc_conv_descriptor_lbound_set (&block, dest,
+				      gfc_rank_cst[n], lbound);
       gfc_conv_descriptor_ubound_set (&block, dest,
 				      gfc_rank_cst[n], tmp);
-      gfc_conv_descriptor_lbound_set (&block, dest,
-				      gfc_rank_cst[n], lbound);
 
       tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
 			 gfc_conv_descriptor_lbound_get (dest,
Index: libgfortran/io/list_read.c
===================================================================
--- libgfortran/io/list_read.c	(Revision 185103)
+++ libgfortran/io/list_read.c	(Arbeitskopie)
@@ -2894,7 +2894,10 @@ get_name:
 
   if (c == '(' && nl->type == BT_CHARACTER)
     {
-      descriptor_dimension chd[1] = { {1, clow, nl->string_length} };
+/* FIXME: Sets stride, lower_bound, _ubound, sm, extent, but extend
+   should be kind dependent. Cf. also PR 52539.  */
+      descriptor_dimension chd[1] = { {1, clow, nl->string_length, 1,
+				       nl->string_length - clow + 1} };
       array_loop_spec ind[1] = { {1, clow, nl->string_length, 1} };
 
       if (nml_parse_qualifier (dtp, chd, ind, -1, nml_err_msg, 
Index: libgfortran/libgfortran.h
===================================================================
--- libgfortran/libgfortran.h	(Revision 185103)
+++ libgfortran/libgfortran.h	(Arbeitskopie)
@@ -369,16 +369,9 @@ typedef GFC_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS,
 #define GFC_DESCRIPTOR_DTYPE(desc) ((desc)->dtype)
 
 #define GFC_DIMENSION_LBOUND(dim) ((dim).lower_bound)
-/* Old. */
-#define GFC_DIMENSION_UBOUND(dim) ((dim)._ubound)
-#define GFC_DIMENSION_EXTENT(dim) ((dim).ubound + 1 - (dim).lower_bound)
+#define GFC_DIMENSION_UBOUND(dim) ((dim).lower_bound + (dim).extent - 1)
+#define GFC_DIMENSION_EXTENT(dim) ((dim).extent)
 
-/* New. */
-/*
-  #define GFC_DIMENSION_UBOUND(dim) ((dim).lower_bound + (dim).extent - 1)
-  #define GFC_DIMENSION_EXTENT(dim) ((dim).extent)
-*/
-
 #define GFC_DIMENSION_SET(dim,lb,ub,str) \
   do \
     { \
Index: libgfortran/ChangeLog.fortran-dev
===================================================================
--- libgfortran/ChangeLog.fortran-dev	(Revision 185103)
+++ libgfortran/ChangeLog.fortran-dev	(Arbeitskopie)
@@ -1,3 +1,9 @@
+2012-03-10  Tobias Burnus  <burnus@net-b.de>
+
+	* libgfortran.h	(GFC_DIMENSION_UBOUND, GFC_DIMENSION_EXTENT):
+	Use extent and lower_bound internally.
+	* io/list_read.c (nml_get_obj_data): Set also sm and extent.
+
 2012-03-06  Tobias Burnus  <burnus@net-b.de>
 
 	* ISO_Fortran_binding.h: New.
