utils2.c (build_call_alloc_dealloc): Move the code retrieving an allocator return...
authorOlivier Hainque <hainque@adacore.com>
Fri, 16 Nov 2007 08:52:51 +0000 (08:52 +0000)
committerOlivier Hainque <hainque@gcc.gnu.org>
Fri, 16 Nov 2007 08:52:51 +0000 (08:52 +0000)
2007-11-16  Olivier Hainque  <hainque@adacore.com>

        ada/
        * utils2.c (build_call_alloc_dealloc) <if gnu_obj>: Move the code
        retrieving an allocator return value from a super-aligned address from
        here to ...
        * trans.c (gnat_to_gnu) <case N_Free_Statement>: ... here, and don't
        expect a super-aligned address for a fat or thin pointer.

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

From-SVN: r130221

gcc/ada/ChangeLog
gcc/ada/trans.c
gcc/ada/utils2.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/release_unc_maxalign.adb [new file with mode: 0644]

index c90fe05c504c5ea696eca19c5a7894fb84bc45f2..0faaf57494685627e98794037b63796c8b6bf70d 100644 (file)
@@ -1,3 +1,11 @@
+2007-11-16  Olivier Hainque  <hainque@adacore.com>
+
+       * utils2.c (build_call_alloc_dealloc) <if gnu_obj>: Move the code
+       retrieving an allocator return value from a super-aligned address from
+       here to ...
+       * trans.c (gnat_to_gnu) <case N_Free_Statement>: ... here, and don't
+       expect a super-aligned address for a fat or thin pointer.
+       
 2007-11-14  Eric Botcazou  <ebotcazou@adacore.com>
 
        * trans.c (call_to_gnu): Always set the source location on the call
index cd3c6a6be0f18772db46f0da55ab09952245c28c..449f0f7fc3a0168982653631c58bea7cd2ed07fa 100644 (file)
@@ -4565,7 +4565,9 @@ gnat_to_gnu (Node_Id gnat_node)
          tree gnu_obj_type;
          tree gnu_actual_obj_type = 0;
          tree gnu_obj_size;
-         int align;
+         unsigned int align;
+         unsigned int default_allocator_alignment
+           = get_target_default_allocator_alignment () * BITS_PER_UNIT;
 
          /* If this is a thin pointer, we must dereference it to create
             a fat pointer, then go back below to a thin pointer.  The
@@ -4621,6 +4623,35 @@ gnat_to_gnu (Node_Id gnat_node)
                                         gnu_ptr, gnu_byte_offset);
            }
 
+         /* If the object was allocated from the default storage pool, the
+            alignement was greater than what the allocator provides, and this
+            is not a fat or thin pointer, what we have in gnu_ptr here is an
+            address dynamically adjusted to match the alignment requirement
+            (see build_allocator).  What we need to pass to free is the
+            initial allocator's return value, which has been stored just in
+            front of the block we have.  */
+         if (No (Procedure_To_Call (gnat_node)) && align > default_allocator_alignment
+             && ! TYPE_FAT_OR_THIN_POINTER_P (gnu_ptr_type))
+           {
+             /* We set GNU_PTR
+                as * (void **)((void *)GNU_PTR - (void *)sizeof(void *))
+                in two steps: */
+             
+             /* GNU_PTR (void *) = (void *)GNU_PTR - (void *)sizeof (void *))  */
+             gnu_ptr
+               = build_binary_op (MINUS_EXPR, ptr_void_type_node,
+                                  convert (ptr_void_type_node, gnu_ptr),
+                                  convert (ptr_void_type_node,
+                                           TYPE_SIZE_UNIT (ptr_void_type_node)));
+             
+             /* GNU_PTR (void *) = *(void **)GNU_PTR  */
+             gnu_ptr
+               = build_unary_op (INDIRECT_REF, NULL_TREE,
+                                 convert (build_pointer_type (ptr_void_type_node),
+                                          gnu_ptr));
+           }
          gnu_result = build_call_alloc_dealloc (gnu_ptr, gnu_obj_size, align,
                                                 Procedure_To_Call (gnat_node),
                                                 Storage_Pool (gnat_node),
index 350358f719ba449f4d49e77689d874660367209f..b8f59477af59a8afda3d251d39ef3322420138a9 100644 (file)
@@ -1873,39 +1873,7 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, unsigned align,
     }
 
   else if (gnu_obj)
-    {
-      /* If the required alignement was greater than what the default
-        allocator guarantees, what we have in gnu_obj here is an address
-        dynamically adjusted to match the requirement (see build_allocator).
-        What we need to pass to free is the initial underlying allocator's
-        return value, which has been stored just in front of the block we
-        have.  */
-
-      unsigned int default_allocator_alignment
-       = get_target_default_allocator_alignment () * BITS_PER_UNIT;
-
-      if (align > default_allocator_alignment)
-       {
-         /* We set GNU_OBJ
-            as * (void **)((void *)GNU_OBJ - (void *)sizeof(void *))
-            in two steps: */
-
-         /* GNU_OBJ (void *) = (void *)GNU_OBJ - (void *)sizeof (void *))  */
-         gnu_obj
-           = build_binary_op (MINUS_EXPR, ptr_void_type_node,
-                              convert (ptr_void_type_node, gnu_obj),
-                              convert (ptr_void_type_node,
-                                       TYPE_SIZE_UNIT (ptr_void_type_node)));
-
-         /* GNU_OBJ (void *) = *(void **)GNU_OBJ  */
-         gnu_obj
-           = build_unary_op (INDIRECT_REF, NULL_TREE,
-                             convert (build_pointer_type (ptr_void_type_node),
-                                      gnu_obj));
-       }
-
-      return build_call_1_expr (free_decl, gnu_obj);
-    }
+    return build_call_1_expr (free_decl, gnu_obj);
 
   /* ??? For now, disable variable-sized allocators in the stack since
      we can't yet gimplify an ALLOCATE_EXPR.  */
index ec46967d4c83eb82bea8b07f942529ad96e774bb..0ef30d2a02e47607b43a2acf6c487ee3fb61a9d3 100644 (file)
@@ -1,3 +1,7 @@
+2007-11-16  Olivier Hainque  <hainque@adacore.com>
+
+       * gnat.dg/release_unc_maxalign.adb: New test.
+
 2007-11-16  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/34100
diff --git a/gcc/testsuite/gnat.dg/release_unc_maxalign.adb b/gcc/testsuite/gnat.dg/release_unc_maxalign.adb
new file mode 100644 (file)
index 0000000..245ce21
--- /dev/null
@@ -0,0 +1,19 @@
+-- { dg-do run }
+
+with Ada.Unchecked_Deallocation;
+
+procedure Release_UNC_Maxalign is
+
+   type List is array (Natural range <>) of Integer;
+   for List'Alignment use Standard'Maximum_Alignment;
+
+   type List_Access is access all List;
+
+   procedure Release is new Ada.Unchecked_Deallocation
+     (Object => List, Name => List_Access);
+
+   My_List : List_Access;
+begin
+   My_List := new List (1 .. 3);
+   Release (My_List);
+end;