]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
decl.c (gnat_to_gnu_entity): Force all local variables with aggregate types in memory...
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 13 Oct 2013 17:20:58 +0000 (17:20 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 13 Oct 2013 17:20:58 +0000 (17:20 +0000)
* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Force all local
variables with aggregate types in memory if not optimizing.

From-SVN: r203507

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/uninit_array.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/uninit_array.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/uninit_array_pkg.ads [new file with mode: 0644]

index e97b56c26e5d0bbf3c433d19e5ffbb1846636d62..99cac5fa0be0326298073f641dba7a629ff1ff6f 100644 (file)
@@ -1,3 +1,8 @@
+2013-10-13  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Force all local
+       variables with aggregate types in memory if not optimizing.
+
 2013-10-13  Hristian Kirtchev  <kirtchev@adacore.com>
 
        * sem_prag.adb (Check_Mode): Do
index 6b1e2a5e307bde35053358ea175384d93770540b..57dfff171a600c3da14a90efcb1b6ed7d248bdec 100644 (file)
@@ -1497,7 +1497,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
        /* If we are defining an Out parameter and optimization isn't enabled,
           create a fake PARM_DECL for debugging purposes and make it point to
           the VAR_DECL.  Suppress debug info for the latter but make sure it
-          will live on the stack so that it can be accessed from within the
+          will live in memory so that it can be accessed from within the
           debugger through the PARM_DECL.  */
        if (kind == E_Out_Parameter
            && definition
@@ -1520,7 +1520,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
        /* If this is a renaming pointer, attach the renamed object to it and
           register it if we are at the global level.  Note that an external
           constant is at the global level.  */
-       else if (TREE_CODE (gnu_decl) == VAR_DECL && renamed_obj)
+       if (TREE_CODE (gnu_decl) == VAR_DECL && renamed_obj)
          {
            SET_DECL_RENAMED_OBJECT (gnu_decl, renamed_obj);
            if ((!definition && kind == E_Constant) || global_bindings_p ())
@@ -1579,6 +1579,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
            && Has_Nested_Block_With_Handler (Scope (gnat_entity)))
          TREE_ADDRESSABLE (gnu_decl) = 1;
 
+       /* If this is a local variable with non-BLKmode and aggregate type,
+          and optimization isn't enabled, then force it in memory so that
+          a register won't be allocated to it with possible subparts left
+          uninitialized and reaching the register allocator.  */
+       else if (TREE_CODE (gnu_decl) == VAR_DECL
+                && !DECL_EXTERNAL (gnu_decl)
+                && !TREE_STATIC (gnu_decl)
+                && DECL_MODE (gnu_decl) != BLKmode
+                && AGGREGATE_TYPE_P (TREE_TYPE (gnu_decl))
+                && !TYPE_IS_FAT_POINTER_P (TREE_TYPE (gnu_decl))
+                && !optimize)
+         TREE_ADDRESSABLE (gnu_decl) = 1;
+
        /* If we are defining an object with variable size or an object with
           fixed size that will be dynamically allocated, and we are using the
           setjmp/longjmp exception mechanism, update the setjmp buffer.  */
index 362186f2628defffc1aa04e1214e68531d5b9aee..a364e7446b0768146f27c2913a6923e3acff19ef 100644 (file)
@@ -1,3 +1,8 @@
+2013-10-13  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/uninit_array.ad[sn]: New test.
+       * gnat.dg/uninit_array_pkg.ads: New helper.
+
 2013-10-13  Richard Biener  <rguenther@suse.de>
 
        * gcc.c-torture/execute/pr58662.c: New test.
diff --git a/gcc/testsuite/gnat.dg/uninit_array.adb b/gcc/testsuite/gnat.dg/uninit_array.adb
new file mode 100644 (file)
index 0000000..910bdaf
--- /dev/null
@@ -0,0 +1,22 @@
+-- { dg-do compile }\r
+-- { dg-options "-gnatws" }\r
+\r
+with Uninit_Array_Pkg; use Uninit_Array_Pkg;\r
+\r
+package body Uninit_Array is\r
+\r
+  function F1 return Integer;\r
+  pragma Inline_Always (F1);\r
+\r
+  function F1 return Integer is\r
+    Var : Arr;\r
+  begin\r
+    return F (Var(Var'First(1)));\r
+  end;\r
+\r
+  function F2 return Integer is\r
+  begin\r
+    return F1;\r
+  end;\r
+\r
+end Uninit_Array;\r
diff --git a/gcc/testsuite/gnat.dg/uninit_array.ads b/gcc/testsuite/gnat.dg/uninit_array.ads
new file mode 100644 (file)
index 0000000..7245221
--- /dev/null
@@ -0,0 +1,5 @@
+package Uninit_Array is\r
+\r
+  function F2 return Integer;\r
+\r
+end Uninit_Array;\r
diff --git a/gcc/testsuite/gnat.dg/uninit_array_pkg.ads b/gcc/testsuite/gnat.dg/uninit_array_pkg.ads
new file mode 100644 (file)
index 0000000..566632a
--- /dev/null
@@ -0,0 +1,11 @@
+package Uninit_Array_Pkg Is\r
+\r
+  type Rec is record\r
+    B1, B2, B3, B4: Boolean;\r
+  end record;\r
+\r
+  type Arr is array (Boolean) of Rec;\r
+\r
+  function F (R : Rec) return Integer;\r
+\r
+end Uninit_Array_Pkg;\r