This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Fix ICE on uninitialized array local variable

This fixes an ICE on a rare conjunction of pragma Inline_Always, 2-element 
array and uninitialized local variable.

Tested on x86_64-suse-linux, applied on the mainline.

2013-10-13  Eric Botcazou  <>

	* gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Force all local
	variables with aggregate types in memory if not optimizing.

2013-10-13  Eric Botcazou  <>

	* gnat.dg/[sn]: New test.
	* gnat.dg/ New helper.

Eric Botcazou
Index: gcc-interface/decl.c
--- gcc-interface/decl.c	(revision 203499)
+++ gcc-interface/decl.c	(working copy)
@@ -1497,7 +1497,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	/* 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_entit
 	/* 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_entit
 	    && 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.  */
-- { 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;
    return F (Var(Var'First(1)));

  function F2 return Integer is
    return F1;

end Uninit_Array;
package Uninit_Array is

  function F2 return Integer;

end Uninit_Array;
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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]