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 <[email protected]>
* 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 <[email protected]>
* 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;