aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2013-10-13 17:20:58 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2013-10-13 17:20:58 +0000
commitf036807af8c8ac6a558066b16b697c2a475770e9 (patch)
treec45a8f551c60e4fa10a2ccc89a5b0e8a78710df6 /gcc
parentd67f5bbb91c2919672cf9dade30312fc331ffbb3 (diff)
downloadgcc-f036807af8c8ac6a558066b16b697c2a475770e9.zip
gcc-f036807af8c8ac6a558066b16b697c2a475770e9.tar.gz
gcc-f036807af8c8ac6a558066b16b697c2a475770e9.tar.bz2
decl.c (gnat_to_gnu_entity): Force all local variables with aggregate types in memory if not optimizing.
* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Force all local variables with aggregate types in memory if not optimizing. From-SVN: r203507
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/ChangeLog5
-rw-r--r--gcc/ada/gcc-interface/decl.c17
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gnat.dg/uninit_array.adb22
-rw-r--r--gcc/testsuite/gnat.dg/uninit_array.ads5
-rw-r--r--gcc/testsuite/gnat.dg/uninit_array_pkg.ads11
6 files changed, 63 insertions, 2 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index e97b56c..99cac5f 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -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
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 6b1e2a5..57dfff1 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 362186f..a364e74 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..910bdaf
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/uninit_array.adb
@@ -0,0 +1,22 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
+with Uninit_Array_Pkg; use Uninit_Array_Pkg;
+
+package body Uninit_Array is
+
+ function F1 return Integer;
+ pragma Inline_Always (F1);
+
+ function F1 return Integer is
+ Var : Arr;
+ begin
+ return F (Var(Var'First(1)));
+ end;
+
+ function F2 return Integer is
+ begin
+ return F1;
+ end;
+
+end Uninit_Array;
diff --git a/gcc/testsuite/gnat.dg/uninit_array.ads b/gcc/testsuite/gnat.dg/uninit_array.ads
new file mode 100644
index 0000000..7245221
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/uninit_array.ads
@@ -0,0 +1,5 @@
+package Uninit_Array is
+
+ function F2 return Integer;
+
+end Uninit_Array;
diff --git a/gcc/testsuite/gnat.dg/uninit_array_pkg.ads b/gcc/testsuite/gnat.dg/uninit_array_pkg.ads
new file mode 100644
index 0000000..566632a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/uninit_array_pkg.ads
@@ -0,0 +1,11 @@
+package Uninit_Array_Pkg Is
+
+ type Rec is record
+ B1, B2, B3, B4: Boolean;
+ end record;
+
+ type Arr is array (Boolean) of Rec;
+
+ function F (R : Rec) return Integer;
+
+end Uninit_Array_Pkg;