From e16856980de702ae75163acb8dd2daa038d153b0 Mon Sep 17 00:00:00 2001
From: hainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 21 Aug 2006 16:01:03 +0000
Subject: [PATCH] 	* gimplify.c (gimplify_init_constructor)
 <RECORD,UNION,ARRAY types>: 	Arrange for the temporary captures of
 components overlapping the lhs 	to happen before the lhs is possibly
 cleared.

testsuite/
	* gnat.dg/self_aggregate_with_zeros.adb: New test.
	* gnat.dg/self_aggregate_with_array.adb: New test.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116300 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                                 |  6 +++++
 gcc/gimplify.c                                | 25 +++++++++++--------
 gcc/testsuite/ChangeLog                       |  5 ++++
 .../gnat.dg/self_aggregate_with_array.adb     | 21 ++++++++++++++++
 .../gnat.dg/self_aggregate_with_zeros.adb     | 19 ++++++++++++++
 5 files changed, 66 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/gnat.dg/self_aggregate_with_array.adb
 create mode 100644 gcc/testsuite/gnat.dg/self_aggregate_with_zeros.adb

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b0143f71ba66..8e3a0ad12fd7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-08-21  Olivier Hainque  <hainque@adacore.com>
+
+	* gimplify.c (gimplify_init_constructor) <RECORD,UNION,ARRAY types>:
+	Arrange for the temporary captures of components overlapping the lhs
+	to happen before the lhs is possibly cleared.
+	
 2006-08-21  Mark Shinwell  <shinwell@codesourcery.com>
  
 	* config/arm/pr-support.c (__gnu_unwind_execute): Insert " + 1" in
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e2586a0f8222..6ade10cca299 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3061,6 +3061,20 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
 	      }
 	  }
 
+	/* If there are nonzero elements, pre-evaluate to capture elements
+	   overlapping with the lhs into temporaries.  We must do this before
+	   clearing to fetch the values before they are zeroed-out.  */
+	if (num_nonzero_elements > 0)
+	  {
+	    preeval_data.lhs_base_decl = get_base_address (object);
+	    if (!DECL_P (preeval_data.lhs_base_decl))
+	      preeval_data.lhs_base_decl = NULL;
+	    preeval_data.lhs_alias_set = get_alias_set (object);
+
+	    gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
+					pre_p, post_p, &preeval_data);
+	  }
+
 	if (cleared)
 	  {
 	    /* Zap the CONSTRUCTOR element list, which simplifies this case.
@@ -3076,16 +3090,7 @@ gimplify_init_constructor (tree *expr_p, tree *pre_p,
 	   elements in the constructor, add assignments to the individual
 	   scalar fields of the object.  */
 	if (!cleared || num_nonzero_elements > 0)
-	  {
-	    preeval_data.lhs_base_decl = get_base_address (object);
-	    if (!DECL_P (preeval_data.lhs_base_decl))
-	      preeval_data.lhs_base_decl = NULL;
-	    preeval_data.lhs_alias_set = get_alias_set (object);
-
-	    gimplify_init_ctor_preeval (&TREE_OPERAND (*expr_p, 1),
-					pre_p, post_p, &preeval_data);
-	    gimplify_init_ctor_eval (object, elts, pre_p, cleared);
-	  }
+	  gimplify_init_ctor_eval (object, elts, pre_p, cleared);
 
 	*expr_p = NULL_TREE;
       }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0f92e5f64657..d6e011ce9b47 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-08-21  Olivier Hainque  <hainque@adacore.com>
+
+	* gnat.dg/self_aggregate_with_zeros.adb: New test.
+	* gnat.dg/self_aggregate_with_array.adb: New test.
+
 2006-08-21  Mark Shinwell  <shinwell@codesourcery.com>
  
  	* g++.dg/eh/arm-vfp-unwind.C: New test.
diff --git a/gcc/testsuite/gnat.dg/self_aggregate_with_array.adb b/gcc/testsuite/gnat.dg/self_aggregate_with_array.adb
new file mode 100644
index 000000000000..850e5defffc5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/self_aggregate_with_array.adb
@@ -0,0 +1,21 @@
+-- { dg-do run }
+
+procedure self_aggregate_with_array is
+
+   type Value_Bounds is array (1 .. 2) of Natural;
+
+   type Sensor is record
+      Value  : Natural;
+      Bounds : Value_Bounds;
+   end record;
+
+   Pressure : Sensor;
+
+begin
+   Pressure.Value := 256;
+   Pressure := (Value => Pressure.Value, Bounds => (1, 2));
+
+   if Pressure.Value /= 256 then
+      raise Program_Error;
+   end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/self_aggregate_with_zeros.adb b/gcc/testsuite/gnat.dg/self_aggregate_with_zeros.adb
new file mode 100644
index 000000000000..f774fcdf6a5a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/self_aggregate_with_zeros.adb
@@ -0,0 +1,19 @@
+-- { dg-do run }
+
+procedure self_aggregate_with_zeros is
+
+   type Sensor is record
+      Value  : Natural;
+      A, B, C, D, E, F, G, H, I, J, K, L, M : Natural;
+   end record;
+
+   Pressure : Sensor;
+
+begin
+   Pressure.Value := 256;
+   Pressure := (Pressure.Value, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+   if Pressure.Value /= 256 then
+      raise Program_Error;
+   end if;
+end;
-- 
GitLab