One method (for more detail, look up Controlled types in an Ada book, or see section 7.4 of the Ada 95 Rationale): with Finalization; ........ type A is access .....; type Needs_Guaranteed_Heap_Cleanup is new Finalization.Controlled with record Pointer : A; end record; .... procedure Finalize (Item : Needs_Guaranteed_Heap_Cleanup) is -- automatically called when Item exits scope. -- client of Item cannot prevent it (or forget it). begin Free (Item.Pointer); Finalize (Controlled(Item)); end Finalize; type File_That_Needs_Guaranteed_Closing is new Finalization.Controlled with record File : XXX_IO.File_Type; end record; .... procedure Finalize (Item : File_That_Needs_Guaranteed_Closing) is -- automatically called when Item exits scope. -- client of Item cannot prevent it (or forget it). begin if XXX_IO.Is_Open (Item.File) then XXX_IO.Close (Item.File); end if; Finalize (Controlled(Item)); end Finalize; Another method is described in an article on the Web. URI recently posted in comp.lang.ada but I don't remember it.