OSDN Git Service

2008-06-13 Olivier Hainque <hainque@adacore.com>
authorhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jun 2008 22:07:28 +0000 (22:07 +0000)
committerhainque <hainque@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Jun 2008 22:07:28 +0000 (22:07 +0000)
ada/
* decl.c (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): Define to 0
if undefined.
(gnat_to_gnu_entity) <case E_Function/Procedure>: Request stack
realignment with force_align_arg_pointer attribute on foreign
convention subprograms if FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN.

testsuite/
* gnat.dg/task_stack_align.adb: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@136768 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ada/ChangeLog
gcc/ada/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/task_stack_align.adb [new file with mode: 0644]

index f0eb327..2ad33ef 100644 (file)
@@ -1,5 +1,13 @@
 2008-06-13  Olivier Hainque  <hainque@adacore.com>
 
+       * decl.c (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): Define to 0
+       if undefined.
+       (gnat_to_gnu_entity) <case E_Function/Procedure>: Request stack
+       realignment with force_align_arg_pointer attribute on foreign
+       convention subprograms if FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN.
+       
+2008-06-13  Olivier Hainque  <hainque@adacore.com>
+
        * utils.c (rest_of_record_type_compilation): When computing
        encodings for the components of a variable size type, early
        strip conversions on the current position expression to make
index dbd7970..ff2927f 100644 (file)
 #define Has_Stdcall_Convention(E) (0)
 #endif
 
+/* Stack realignment for functions with foreign conventions is provided on a
+   per back-end basis now, as it is handled by the prologue expanders and not
+   as part of the function's body any more.  It might be requested by way of a
+   dedicated function type attribute on the targets that support it.
+
+   We need a way to avoid setting the attribute on the targets that don't
+   support it and use FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN for this purpose.
+
+   It is defined on targets where the circuitry is available, and indicates
+   whether the realignment is needed for 'main'. We use this to decide for
+   foreign subprograms as well.
+
+   It is not defined on targets where the circuitry is not implemented, and
+   we just never set the attribute in these cases.
+
+   Whether it is defined on all targets that would need it in theory is
+   not entirely clear.  We currently trust the base GCC settings for this
+   purpose.  */
+
+#ifndef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN 0
+#endif
+
 struct incomplete
 {
   struct incomplete *next;
@@ -3951,6 +3974,19 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
             get_identifier ("stdcall"), NULL_TREE,
             gnat_entity);
 
+       /* If we are on a target where stack realignment is needed for 'main'
+          to honor GCC's implicit expectations (stack alignment greater than
+          what the base ABI guarantees), ensure we do the same for foreign
+          convention subprograms as they might be used as callbacks from code
+          breaking such expectations.  Note that this applies to task entry
+          points in particular.  */
+       if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+           && Has_Foreign_Convention (gnat_entity))
+         prepend_one_attribute_to
+           (&attr_list, ATTR_MACHINE_ATTRIBUTE,
+            get_identifier ("force_align_arg_pointer"), NULL_TREE,
+            gnat_entity);
+
        /* The lists have been built in reverse.  */
        gnu_param_list = nreverse (gnu_param_list);
        if (has_stub)
index dd044c2..6ddf1ce 100644 (file)
@@ -1,3 +1,7 @@
+2008-06-13  Olivier Hainque  <hainque@adacore.com>
+
+       * gnat.dg/task_stack_align.adb: New test.
+
 2008-06-13  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/35863
diff --git a/gcc/testsuite/gnat.dg/task_stack_align.adb b/gcc/testsuite/gnat.dg/task_stack_align.adb
new file mode 100644 (file)
index 0000000..1151a91
--- /dev/null
@@ -0,0 +1,31 @@
+-- { dg-do run }
+
+with Ada.Text_IO; use Ada.Text_IO;
+with System.Storage_Elements; use System.Storage_Elements;
+
+procedure Task_Stack_Align is
+
+   type Align_Me is record
+      Value : Integer;
+   end record;
+   for Align_Me'Alignment use Standard'Maximum_Alignment;
+
+   procedure Check_Local_Alignment_From (Context : String) is
+      Object : Align_Me;
+   begin
+      if To_Integer (Object'Address) mod Object'Alignment /= 0 then
+         Put_Line ("alignment check failed in " & Context);
+      end if;
+   end;
+
+   task type T;
+
+   task body T is
+   begin
+      Check_Local_Alignment_From ("task T");
+   end;
+
+   Tasks : array (1 .. 50) of T;
+begin
+   Check_Local_Alignment_From ("environment");
+end;