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;

Reply via email to