diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 8c254dd..08f5a38 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -6443,6 +6443,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
 	  if (expr->ts.type == BT_CHARACTER)
 	    se->string_length = gfc_get_expr_charlen (expr);
 
+	  gfc_free_ss (ss);
 	  return;
 	}
       break;
@@ -6477,6 +6478,7 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
 	    gcc_assert (se->ss == ss);
 	  se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
 	  gfc_conv_expr (se, expr);
+	  gfc_free_ss (ss);
 	  return;
 	}
 
@@ -6986,6 +6988,7 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77,
 	    se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
 	  if (size)
 	    array_parameter_size (tmp, expr, size);
+	  gfc_free_ss (ss);
 	  return;
         }
 
@@ -6996,6 +6999,8 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, bool g77,
 	      gfc_conv_expr_descriptor (se, expr, ss);
 	      tmp = se->expr;
 	    }
+	  else
+	    gfc_free_ss (ss);
 	  if (size)
 	    array_parameter_size (tmp, expr, size);
 	  se->expr = gfc_conv_array_data (tmp);
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index cfb0862..28f8d28 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -3534,7 +3534,6 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol * sym,
       gfc_add_block_to_block (&block, &loop.post);
       gfc_add_block_to_block (&block, &fptrse.post);
       gfc_cleanup_loop (&loop);
-      gfc_free_ss (ss);
 
       gfc_add_modify (&block, offset, 
 		      fold_build1_loc (input_location, NEGATE_EXPR,
@@ -4040,28 +4039,34 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
 
 	      if (e->expr_type == EXPR_VARIABLE
 		    && is_subref_array (e))
-		/* The actual argument is a component reference to an
-		   array of derived types.  In this case, the argument
-		   is converted to a temporary, which is passed and then
-		   written back after the procedure call.  */
-		gfc_conv_subref_array_arg (&parmse, e, f,
+		{
+		  /* The actual argument is a component reference to an
+		     array of derived types.  In this case, the argument
+		     is converted to a temporary, which is passed and then
+		     written back after the procedure call.  */
+		  gfc_conv_subref_array_arg (&parmse, e, f,
 				fsym ? fsym->attr.intent : INTENT_INOUT,
 				fsym && fsym->attr.pointer);
+		  gfc_free_ss (argss);
+		}
 	      else if (gfc_is_class_array_ref (e, NULL)
 			 && fsym && fsym->ts.type == BT_DERIVED)
-		/* The actual argument is a component reference to an
-		   array of derived types.  In this case, the argument
-		   is converted to a temporary, which is passed and then
-		   written back after the procedure call.
-		   OOP-TODO: Insert code so that if the dynamic type is
-		   the same as the declared type, copy-in/copy-out does
-		   not occur.  */
-		gfc_conv_subref_array_arg (&parmse, e, f,
+		{
+		  /* The actual argument is a component reference to an
+		     array of derived types.  In this case, the argument
+		     is converted to a temporary, which is passed and then
+		     written back after the procedure call.
+		     OOP-TODO: Insert code so that if the dynamic type is
+		     the same as the declared type, copy-in/copy-out does
+		     not occur.  */
+		  gfc_conv_subref_array_arg (&parmse, e, f,
 				fsym ? fsym->attr.intent : INTENT_INOUT,
 				fsym && fsym->attr.pointer);
+		  gfc_free_ss (argss);
+		}
 	      else
-	        gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
-					  sym->name, NULL);
+		  gfc_conv_array_parameter (&parmse, e, argss, f, fsym,
+					    sym->name, NULL);
 
 	      /* If an ALLOCATABLE dummy argument has INTENT(OUT) and is 
 		 allocated on entry, it must be deallocated.  */
@@ -6771,7 +6776,6 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
       if (!expr2->value.function.isym)
 	{
 	  realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
-	  gfc_cleanup_loop (&loop);
 	  ss->is_alloc_lhs = 1;
 	}
       else
@@ -6780,7 +6784,6 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
 
   gfc_conv_function_expr (&se, expr2);
   gfc_add_block_to_block (&se.pre, &se.post);
-  gfc_free_ss (se.ss);
 
   return gfc_finish_block (&se.pre);
 }
@@ -7380,7 +7383,6 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
       /* Wrap the whole thing up.  */
       gfc_add_block_to_block (&block, &loop.pre);
       gfc_add_block_to_block (&block, &loop.post);
-
       gfc_cleanup_loop (&loop);
     }
 
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index d0aebe9..fac29c7 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -1328,7 +1328,6 @@ gfc_conv_intrinsic_rank (gfc_se *se, gfc_expr *expr)
   argse.descriptor_only = 1;
 
   gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr, ss);
-  gfc_free_ss (ss);
   gfc_add_block_to_block (&se->pre, &argse.pre);
   gfc_add_block_to_block (&se->post, &argse.post);
 
