Index: gcc/fortran/ChangeLog
===================================================================
--- gcc/fortran/ChangeLog	(revision 190750)
+++ gcc/fortran/ChangeLog	(working copy)
@@ -1,6 +1,15 @@
 2012-08-28  Tobias Burnus  <burnus@net-b.de>
 
 	PR fortran/54384
+	* decl.c (match_data_constant): Add missing gfc_free_expr.
+	(top_val_list): Remove always-true condition.
+	* data.c (get_array_index, create_character_initializer):
+	Free temporary expressions.
+	(gfc_assign_data_value): Free expression when aborting.
+
+2012-08-28  Tobias Burnus  <burnus@net-b.de>
+
+	PR fortran/54384
 	* symbol.c (gfc_copy_formal_args): Set also sym->formal_ns.
 
 2012-08-27  Tobias Burnus  <burnus@net-b.de>
Index: gcc/fortran/data.c
===================================================================
--- gcc/fortran/data.c	(revision 190750)
+++ gcc/fortran/data.c	(working copy)
@@ -66,6 +66,7 @@ get_array_index (gfc_array_ref *ar, mpz_t *offset)
 	gfc_error ("non-constant array in DATA statement %L", &ar->where);
 
       mpz_set (tmp, e->value.integer);
+      gfc_free_expr (e);
       mpz_sub (tmp, tmp, ar->as->lower[i]->value.integer);
       mpz_mul (tmp, tmp, delta);
       mpz_add (*offset, tmp, *offset);
@@ -138,8 +139,10 @@ create_character_initializer (gfc_expr *init, gfc_
 	}
 
       gfc_extract_int (start_expr, &start);
+      gfc_free_expr (start_expr);
       start--;
       gfc_extract_int (end_expr, &end);
+      gfc_free_expr (end_expr);
     }
   else
     {
@@ -200,7 +203,7 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr
 {
   gfc_ref *ref;
   gfc_expr *init;
-  gfc_expr *expr;
+  gfc_expr *expr = NULL;
   gfc_constructor *con;
   gfc_constructor *last_con;
   gfc_symbol *symbol;
@@ -500,6 +503,8 @@ gfc_assign_data_value (gfc_expr *lvalue, gfc_expr
   return SUCCESS;
 
 abort:
+  if (!init)
+    gfc_free_expr (expr);
   mpz_clear (offset);
   return FAILURE;
 }
Index: gcc/fortran/decl.c
===================================================================
--- gcc/fortran/decl.c	(revision 190750)
+++ gcc/fortran/decl.c	(working copy)
@@ -361,6 +361,8 @@ match_data_constant (gfc_expr **result)
 	m = MATCH_ERROR;
       return m;
     }
+  else if (m == MATCH_YES)
+    gfc_free_expr (*result);
 
   gfc_current_locus = old_loc;
 
@@ -451,8 +453,7 @@ top_val_list (gfc_data *data)
 	}
       else
 	{
-	  if (expr->ts.type == BT_INTEGER)
-	    mpz_set (tail->repeat, expr->value.integer);
+	  mpz_set (tail->repeat, expr->value.integer);
 	  gfc_free_expr (expr);
 
 	  m = match_data_constant (&tail->expr);
