* stor-layout.c (skip_simple_constant_arithmetic): New function.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Oct 2010 11:02:40 +0000 (11:02 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 Oct 2010 11:02:40 +0000 (11:02 +0000)
(self_referential_size): Use it instead of skip_simple_arithmetic.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165716 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/discr25.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/discr25_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/discr25_pkg.ads [new file with mode: 0644]

index 17cc226..a51fad5 100644 (file)
@@ -1,3 +1,8 @@
+2010-10-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * stor-layout.c (skip_simple_constant_arithmetic): New function.
+       (self_referential_size): Use it instead of skip_simple_arithmetic.
+
 2010-10-20  Olivier Hainque  <hainque@adacore.com>
 
        * config/rs6000/rs6000.c (rs6000_reg_live_or_pic_offset_p):
index 5796ea1..f366318 100644 (file)
@@ -173,6 +173,32 @@ variable_size (tree size)
 /* An array of functions used for self-referential size computation.  */
 static GTY(()) VEC (tree, gc) *size_functions;
 
+/* Look inside EXPR into simple arithmetic operations involving constants.
+   Return the outermost non-arithmetic or non-constant node.  */
+
+static tree
+skip_simple_constant_arithmetic (tree expr)
+{
+  while (true)
+    {
+      if (UNARY_CLASS_P (expr))
+       expr = TREE_OPERAND (expr, 0);
+      else if (BINARY_CLASS_P (expr))
+       {
+         if (TREE_CONSTANT (TREE_OPERAND (expr, 1)))
+           expr = TREE_OPERAND (expr, 0);
+         else if (TREE_CONSTANT (TREE_OPERAND (expr, 0)))
+           expr = TREE_OPERAND (expr, 1);
+         else
+           break;
+       }
+      else
+       break;
+    }
+
+  return expr;
+}
+
 /* Similar to copy_tree_r but do not copy component references involving
    PLACEHOLDER_EXPRs.  These nodes are spotted in find_placeholder_in_expr
    and substituted in substitute_in_expr.  */
@@ -241,7 +267,7 @@ self_referential_size (tree size)
   VEC(tree,gc) *args = NULL;
 
   /* Do not factor out simple operations.  */
-  t = skip_simple_arithmetic (size);
+  t = skip_simple_constant_arithmetic (size);
   if (TREE_CODE (t) == CALL_EXPR)
     return size;
 
index cd27045..12d4bef 100644 (file)
@@ -1,3 +1,8 @@
+2010-10-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/discr25.adb: New test.
+       * gnat.dg/discr25_pkg.ad[sb]: New helper.
+
 2010-10-20  Olivier Hainque  <hainque@adacore.com>
 
        * gcc.target/powerpc/ehreturn.c: New test.
diff --git a/gcc/testsuite/gnat.dg/discr25.adb b/gcc/testsuite/gnat.dg/discr25.adb
new file mode 100644 (file)
index 0000000..a1effea
--- /dev/null
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+
+with Discr25_Pkg;
+
+procedure Discr25 (N : Natural) is
+
+  package Test_Set is new Discr25_Pkg (N);
+
+begin
+  null;
+end;
diff --git a/gcc/testsuite/gnat.dg/discr25_pkg.adb b/gcc/testsuite/gnat.dg/discr25_pkg.adb
new file mode 100644 (file)
index 0000000..59792fd
--- /dev/null
@@ -0,0 +1,24 @@
+package body Discr25_Pkg is
+
+  type Arr1 is array (Natural range <>) of Integer;
+
+  B : constant Boolean := N > 0;
+
+  type Arr2 is array (True .. B) of Integer;
+
+  type Obj_T (Size_Max : Natural) is record
+    A2 : Arr2;
+    A1 : Arr1 (0 .. Size_Max);
+  end record;
+
+  procedure Proc1 (Set : in out T) is
+  begin
+    Set := new Obj_T'(Set.all);
+  end;
+
+  procedure Proc2 (Obj : in out T; L : Natural) is
+  begin
+    Obj := new Obj_T (L);
+  end;
+
+end Discr25_Pkg;
diff --git a/gcc/testsuite/gnat.dg/discr25_pkg.ads b/gcc/testsuite/gnat.dg/discr25_pkg.ads
new file mode 100644 (file)
index 0000000..c09634d
--- /dev/null
@@ -0,0 +1,15 @@
+generic
+
+  N : Natural;
+
+package Discr25_Pkg is
+
+  type T is private;
+
+  procedure Proc1 (Set : in out T);
+
+private
+  type Obj_T (Size_Max : Natural);
+  type T is access Obj_T;
+
+end Discr25_Pkg;