From f036807af8c8ac6a558066b16b697c2a475770e9 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 13 Oct 2013 17:20:58 +0000 Subject: [PATCH] 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) : Force all local variables with aggregate types in memory if not optimizing. From-SVN: r203507 --- gcc/ada/ChangeLog | 5 +++++ gcc/ada/gcc-interface/decl.c | 17 +++++++++++++++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gnat.dg/uninit_array.adb | 22 ++++++++++++++++++++++ gcc/testsuite/gnat.dg/uninit_array.ads | 5 +++++ gcc/testsuite/gnat.dg/uninit_array_pkg.ads | 11 +++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/uninit_array.adb create mode 100644 gcc/testsuite/gnat.dg/uninit_array.ads create mode 100644 gcc/testsuite/gnat.dg/uninit_array_pkg.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index e97b56c26e5d..99cac5fa0be0 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,8 @@ +2013-10-13 Eric Botcazou + + * gcc-interface/decl.c (gnat_to_gnu_entity) : Force all local + variables with aggregate types in memory if not optimizing. + 2013-10-13 Hristian Kirtchev * sem_prag.adb (Check_Mode): Do diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c index 6b1e2a5e307b..57dfff171a60 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 362186f2628d..a364e7446b07 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-10-13 Eric Botcazou + + * gnat.dg/uninit_array.ad[sn]: New test. + * gnat.dg/uninit_array_pkg.ads: New helper. + 2013-10-13 Richard Biener * 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 000000000000..910bdaf431ac --- /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 000000000000..72452213e023 --- /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 000000000000..566632a270d9 --- /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; -- 2.47.2