-- { dg-do run } with System.Storage_Elements; use System.Storage_Elements; with Ada.Unchecked_Deallocation; procedure Align_MAX is Align : constant := Standard'Maximum_Alignment; generic type Data_Type (<>) is private; type Access_Type is access Data_Type; with function Allocate return Access_Type; with function Address (Ptr : Access_Type) return System.Address; package Check is -- The hooks below just force asm generation that helps associating -- obscure nested function names with their package instance name. Hook_Allocate : System.Address := Allocate'Address; Hook_Address : System.Address := Address'Address; pragma Volatile (Hook_Allocate); pragma Volatile (Hook_Address); procedure Run (Announce : String); end; package body Check is procedure Free is new Ada.Unchecked_Deallocation (Data_Type, Access_Type); procedure Run (Announce : String) is Addr : System.Address; Blocks : array (1 .. 1024) of Access_Type; begin for J in Blocks'Range loop Blocks (J) := Allocate; Addr := Address (Blocks (J)); if Addr mod Data_Type'Alignment /= 0 then raise Program_Error; end if; end loop; for J in Blocks'Range loop Free (Blocks (J)); end loop; end; end; begin declare type Array_Type is array (Integer range <>) of Integer; for Array_Type'Alignment use Align; type FAT_Array_Access is access all Array_Type; function Allocate return FAT_Array_Access is begin return new Array_Type (1 .. 1); end; function Address (Ptr : FAT_Array_Access) return System.Address is begin return Ptr(1)'Address; end; package Check_FAT is new Check (Array_Type, FAT_Array_Access, Allocate, Address); begin Check_FAT.Run ("Checking FAT pointer to UNC array"); end; declare type Array_Type is array (Integer range <>) of Integer; for Array_Type'Alignment use Align; type THIN_Array_Access is access all Array_Type; for THIN_Array_Access'Size use Standard'Address_Size; function Allocate return THIN_Array_Access is begin return new Array_Type (1 .. 1); end; function Address (Ptr : THIN_Array_Access) return System.Address is begin return Ptr(1)'Address; end; package Check_THIN is new Check (Array_Type, THIN_Array_Access, Allocate, Address); begin Check_THIN.Run ("Checking THIN pointer to UNC array"); end; declare type Array_Type is array (Integer range 1 .. 1) of Integer; for Array_Type'Alignment use Align; type Array_Access is access all Array_Type; function Allocate return Array_Access is begin return new Array_Type; end; function Address (Ptr : Array_Access) return System.Address is begin return Ptr(1)'Address; end; package Check_Array is new Check (Array_Type, Array_Access, Allocate, Address); begin Check_Array.Run ("Checking pointer to constrained array"); end; declare type Record_Type is record Value : Integer; end record; for Record_Type'Alignment use Align; type Record_Access is access all Record_Type; function Allocate return Record_Access is begin return new Record_Type; end; function Address (Ptr : Record_Access) return System.Address is begin return Ptr.all'Address; end; package Check_Record is new Check (Record_Type, Record_Access, Allocate, Address); begin Check_Record.Run ("Checking pointer to record"); end; end;