aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gimplify.c25
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/self_aggregate_with_array.adb21
-rw-r--r--gcc/testsuite/gnat.dg/self_aggregate_with_zeros.adb19
5 files changed, 66 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b0143f7..8e3a0ad 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 e2586a0..6ade10c 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 0f92e5f..d6e011c 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 0000000..850e5de
--- /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 0000000..f774fcd
--- /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;