aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2010-04-12 10:00:13 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2010-04-12 10:00:13 +0000
commit675c873bfe795ff94288f31c2735254443d3754b (patch)
tree47f2f8e659d1353465936d33a9982cdbaddb3f3b
parent3fc20697523443ed885f701923160ea22a19be62 (diff)
downloadgcc-675c873bfe795ff94288f31c2735254443d3754b.zip
gcc-675c873bfe795ff94288f31c2735254443d3754b.tar.gz
gcc-675c873bfe795ff94288f31c2735254443d3754b.tar.bz2
expr.c (categorize_ctor_elements_1): Properly count sub-elements of non-constant aggregate elements.
* expr.c (categorize_ctor_elements_1): Properly count sub-elements of non-constant aggregate elements. * gimplify.c (gimplify_init_constructor): Do not pre-evaluate if this is a real initialization. From-SVN: r158219
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/expr.c18
-rw-r--r--gcc/gimplify.c8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gnat.dg/aggr13.adb23
-rw-r--r--gcc/testsuite/gnat.dg/aggr14.adb8
-rw-r--r--gcc/testsuite/gnat.dg/aggr14_pkg.adb16
-rw-r--r--gcc/testsuite/gnat.dg/aggr14_pkg.ads9
8 files changed, 85 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 66b4543..0d4284c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2010-04-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * expr.c (categorize_ctor_elements_1): Properly count sub-elements of
+ non-constant aggregate elements.
+
+ * gimplify.c (gimplify_init_constructor): Do not pre-evaluate if this
+ is a real initialization.
+
2010-04-12 Shujing Zhao <pearly.zhao@oracle.com>
PR c/36774
diff --git a/gcc/expr.c b/gcc/expr.c
index f5de2ae..930ee98 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -4861,9 +4861,8 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
{
- HOST_WIDE_INT mult;
+ HOST_WIDE_INT mult = 1;
- mult = 1;
if (TREE_CODE (purpose) == RANGE_EXPR)
{
tree lo_index = TREE_OPERAND (purpose, 0);
@@ -4925,12 +4924,17 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
break;
default:
- nz_elts += mult;
- elt_count += mult;
+ {
+ HOST_WIDE_INT tc = count_type_elements (TREE_TYPE (value), true);
+ if (tc < 1)
+ tc = 1;
+ nz_elts += mult * tc;
+ elt_count += mult * tc;
- if (const_from_elts_p && const_p)
- const_p = initializer_constant_valid_p (value, TREE_TYPE (value))
- != NULL_TREE;
+ if (const_from_elts_p && const_p)
+ const_p = initializer_constant_valid_p (value, TREE_TYPE (value))
+ != NULL_TREE;
+ }
break;
}
}
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index bfe82dd6..a9eed84 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -3793,10 +3793,10 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
if (notify_temp_creation)
return GS_OK;
- /* 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)
+ /* If there are nonzero elements and if needed, 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 && TREE_CODE (*expr_p) != INIT_EXPR)
{
preeval_data.lhs_base_decl = get_base_address (object);
if (!DECL_P (preeval_data.lhs_base_decl))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 547ea32..1af0673 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-04-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/aggr13.adb: New test.
+ * gnat.dg/aggr14.adb: Likewise.
+ * gnat.dg/aggr14_pkg.ad[sb]: New helper.
+
2010-04-12 Richard Guenther <rguenther@suse.de>
PR c++/43611
diff --git a/gcc/testsuite/gnat.dg/aggr13.adb b/gcc/testsuite/gnat.dg/aggr13.adb
new file mode 100644
index 0000000..add223c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr13.adb
@@ -0,0 +1,23 @@
+-- { dg-do compile }
+-- { dg-options "-fdump-tree-gimple" }
+
+procedure Aggr13 is
+
+ type A is array (Integer range 1 .. 3) of Short_Short_Integer;
+
+ X : A := (1, 2, 3);
+
+ function F return A is
+ begin
+ if X /= (1, 2, 3) then
+ raise Program_Error;
+ end if;
+ return (1, 1, 1);
+ end;
+
+begin
+ X := F;
+end;
+
+-- { dg-final { scan-tree-dump-not "= {}" "gimple" } }
+-- { dg-final { cleanup-tree-dump "gimple" } }
diff --git a/gcc/testsuite/gnat.dg/aggr14.adb b/gcc/testsuite/gnat.dg/aggr14.adb
new file mode 100644
index 0000000..46f5af4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr14.adb
@@ -0,0 +1,8 @@
+-- { dg-do run }
+
+with Aggr14_Pkg; use Aggr14_Pkg;
+
+procedure Aggr14 is
+begin
+ Proc;
+end;
diff --git a/gcc/testsuite/gnat.dg/aggr14_pkg.adb b/gcc/testsuite/gnat.dg/aggr14_pkg.adb
new file mode 100644
index 0000000..ce12960
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr14_pkg.adb
@@ -0,0 +1,16 @@
+package body Aggr14_Pkg is
+
+ function F return A is
+ begin
+ if X /= (1, 2, 3) then
+ raise Program_Error;
+ end if;
+ return (1, 1, 1);
+ end;
+
+ procedure Proc is
+ begin
+ X := F;
+ end;
+
+end Aggr14_Pkg;
diff --git a/gcc/testsuite/gnat.dg/aggr14_pkg.ads b/gcc/testsuite/gnat.dg/aggr14_pkg.ads
new file mode 100644
index 0000000..874e309
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr14_pkg.ads
@@ -0,0 +1,9 @@
+package Aggr14_Pkg is
+
+ type A is array (Integer range 1 .. 3) of Short_Short_Integer;
+
+ X : A := (1, 2, 3);
+
+ procedure Proc;
+
+end Aggr14_Pkg;