We have a call to builtin_alloca_with_align: S10b.27_153 = .builtin_alloca_with_align (5, 8);
and CCP replaces it with a static allocation: S10b.27_153 = &TMP; and is trying to add a special out-of-scope CLOBBER for the new variable TMP, under the assumption that every call to builtin_alloca_with_align is dominated by a call to builtin_stack_save. But this isn't true here: <bb 2>: FRAME.29.M17b = system.secondary_stack.ss_mark (); [return slot optimization] <bb 3>: saved_stack.28_9(ab) = .builtin_stack_save (); because the call to system.secondary_stack.ss_mark creates an abnormal edge to the setjmp dispatcher and we have a setjmp receiver after builtin_stack_save. This is a latent issue and GCC 4.7+ now chokes on it. The way out is to tell the compiler that system.secondary_stack.ss_mark is a well-behaved function, more precisely a "leaf" function. Tested on i586-suse-linux, applied on the mainline and 4.7 branch. 2012-03-25 Eric Botcazou <ebotca...@adacore.com> * gcc-interface/decl.c (SS_MARK_NAME): New define. (gnat_to_gnu_entity) <E_Function>: Prepend leaf attribute on entities whose name is SS_MARK_NAME. 2012-03-25 Eric Botcazou <ebotca...@adacore.com> * gnat.dg/concat2.ad[sb]: New test. -- Eric Botcazou
Index: gcc-interface/decl.c =================================================================== --- gcc-interface/decl.c (revision 185779) +++ gcc-interface/decl.c (working copy) @@ -81,6 +81,9 @@ #define FOREIGN_FORCE_REALIGN_STACK 0 #endif +/* The (internal) name of the System.Secondary_Stack.SS_Mark function. */ +#define SS_MARK_NAME "system__secondary_stack__ss_mark" + struct incomplete { struct incomplete *next; @@ -4405,6 +4408,21 @@ gnat_to_gnu_entity (Entity_Id gnat_entit get_identifier ("force_align_arg_pointer"), NULL_TREE, gnat_entity); + /* ??? Declare System.Secondary_Stack.SS_Mark as leaf, in order to + avoid creating abnormal edges in SJLJ mode, which can break the + dominance relationship if there is a dynamic stack allocation. + We cannot do this in System.Secondary_Stack directly since it's + a compiler unit and this would introduce bootstrap path issues. */ + if (IDENTIFIER_LENGTH (gnu_entity_name) == strlen (SS_MARK_NAME) + && IDENTIFIER_POINTER (gnu_entity_name)[0] == SS_MARK_NAME[0] + && IDENTIFIER_POINTER (gnu_entity_name)[1] == SS_MARK_NAME[1] + && IDENTIFIER_POINTER (gnu_entity_name)[2] == SS_MARK_NAME[2] + && gnu_entity_name == get_identifier (SS_MARK_NAME)) + prepend_one_attribute_to + (&attr_list, ATTR_MACHINE_ATTRIBUTE, + get_identifier ("leaf"), NULL_TREE, + gnat_entity); + /* The lists have been built in reverse. */ gnu_param_list = nreverse (gnu_param_list); if (has_stub)
with Text_IO; use Text_IO; package body Concat2 is function Get_Param return String is begin return ""; end; procedure Browse is Mode : constant String := Get_Param; Mode_Param : constant String := "MODE=" & Mode; begin Put_Line (Mode_Param); end; end Concat2;
-- { dg-do compile } -- { dg-options "-O" } package Concat2 is procedure Browse; end Concat2;