expr.c (categorize_ctor_elements_1): Properly count sub-elements of non-constant...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 12 Apr 2010 10:00:13 +0000 (10:00 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 12 Apr 2010 10:00:13 +0000 (10:00 +0000)
* 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

gcc/ChangeLog
gcc/expr.c
gcc/gimplify.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/aggr13.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/aggr14.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/aggr14_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/aggr14_pkg.ads [new file with mode: 0644]

index 66b4543..0d4284c 100644 (file)
@@ -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
index f5de2ae..930ee98 100644 (file)
@@ -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;
        }
     }
index bfe82dd..a9eed84 100644 (file)
@@ -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))
index 547ea32..1af0673 100644 (file)
@@ -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 (file)
index 0000000..add223c
--- /dev/null
@@ -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 (file)
index 0000000..46f5af4
--- /dev/null
@@ -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 (file)
index 0000000..ce12960
--- /dev/null
@@ -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 (file)
index 0000000..874e309
--- /dev/null
@@ -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;