===================================================================
@@ -739,8 +739,8 @@
if Dispatching_Domains_Used then
WBI (" procedure Freeze_Dispatching_Domains;");
WBI (" pragma Import");
- WBI (" (Ada, Freeze_Dispatching_Domains, " &
- """__gnat_freeze_dispatching_domains"");");
+ WBI (" (Ada, Freeze_Dispatching_Domains, "
+ & """__gnat_freeze_dispatching_domains"");");
end if;
WBI (" begin");
@@ -749,6 +749,18 @@
WBI (" end if;");
WBI (" Is_Elaborated := True;");
+ -- Call System.Elaboration_Allocators.Mark_Start_Of_Elaboration if
+ -- restriction No_Standard_Allocators_After_Elaboration is active.
+
+ if Cumulative_Restrictions.Set
+ (No_Standard_Allocators_After_Elaboration)
+ then
+ WBI (" System.Elaboration_Allocators."
+ & "Mark_Start_Of_Elaboration;");
+ end if;
+
+ -- Generate assignments to initialize globals
+
Set_String (" Main_Priority := ");
Set_Int (Main_Priority);
Set_Char (';');
@@ -996,6 +1008,15 @@
Gen_Elab_Calls;
+ -- Call System.Elaboration_Allocators.Mark_Start_Of_Elaboration if
+ -- restriction No_Standard_Allocators_After_Elaboration is active.
+
+ if Cumulative_Restrictions.Set
+ (No_Standard_Allocators_After_Elaboration)
+ then
+ WBI (" System.Elaboration_Allocators.Mark_End_Of_Elaboration;");
+ end if;
+
-- From this point, no new dispatching domain can be created.
if Dispatching_Domains_Used then
@@ -2482,10 +2503,23 @@
WBI ("with System.Restrictions;");
end if;
+ -- Generate with of Ada.Exceptions if needs library finalization
+
if Needs_Library_Finalization then
WBI ("with Ada.Exceptions;");
end if;
+ -- Generate with of System.Elaboration_Allocators if the restriction
+ -- No_Standard_Allocators_After_Elaboration was present.
+
+ if Cumulative_Restrictions.Set
+ (No_Standard_Allocators_After_Elaboration)
+ then
+ WBI ("with System.Elaboration_Allocators;");
+ end if;
+
+ -- Generate start of package body
+
WBI ("");
WBI ("package body " & Ada_Main & " is");
WBI (" pragma Warnings (Off);");
===================================================================
@@ -241,6 +241,7 @@
System_Dim,
System_DSA_Services,
System_DSA_Types,
+ System_Elaboration_Allocators,
System_Exception_Table,
System_Exceptions_Debug,
System_Exn_Int,
@@ -856,6 +857,8 @@
RE_Any_Container_Ptr, -- System.DSA_Types
+ RE_Check_Standard_Allocator, -- System.Elaboration_Allocators
+
RE_Register_Exception, -- System.Exception_Table
RE_Local_Raise, -- System.Exceptions_Debug
@@ -2141,6 +2144,8 @@
RE_Any_Container_Ptr => System_DSA_Types,
+ RE_Check_Standard_Allocator => System_Elaboration_Allocators,
+
RE_Register_Exception => System_Exception_Table,
RE_Local_Raise => System_Exceptions_Debug,
===================================================================
@@ -4490,6 +4490,20 @@
end if;
end if;
+ -- If no storage pool has been specified and we have the restriction
+ -- No_Standard_Allocators_After_Elaboration is present, then generate
+ -- a call to Elaboration_Allocators.Check_Standard_Allocator.
+
+ if Nkind (N) = N_Allocator
+ and then No (Storage_Pool (N))
+ and then Restriction_Active (No_Standard_Allocators_After_Elaboration)
+ then
+ Insert_Action (N,
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Check_Standard_Allocator), Loc)));
+ end if;
+
-- Handle case of qualified expression (other than optimization above)
-- First apply constraint checks, because the bounds or discriminants
-- in the aggregate might not match the subtype mark in the allocator.
===================================================================
@@ -400,6 +400,7 @@
Type_Id : Entity_Id;
P : Node_Id;
C : Node_Id;
+ Onode : Node_Id;
begin
Check_SPARK_Restriction ("allocator is not allowed", N);
@@ -420,33 +421,40 @@
P := Parent (C);
while Present (P) loop
- -- In both cases we need a handled sequence of statements, where
- -- the occurrence of the allocator is within the statements.
+ -- For the task case we need a handled sequence of statements,
+ -- where the occurrence of the allocator is within the statements
+ -- and the parent is a task body
if Nkind (P) = N_Handled_Sequence_Of_Statements
and then Is_List_Member (C)
and then List_Containing (C) = Statements (P)
then
+ Onode := Original_Node (Parent (P));
+
-- Check for allocator within task body, this is a definite
-- violation of No_Allocators_After_Elaboration we can detect
-- at compile time.
- if Nkind (Original_Node (Parent (P))) = N_Task_Body then
+ if Nkind (Onode) = N_Task_Body then
Check_Restriction
(No_Standard_Allocators_After_Elaboration, N);
exit;
end if;
+ end if;
- -- The other case is appearance in a subprogram body. This may
- -- be a violation if this is a library level subprogram, and it
- -- turns out to be used as the main program, but only the
- -- binder knows that, so just record the occurrence.
+ -- The other case is appearance in a subprogram body. This is
+ -- a violation if this is a library level subprogram with no
+ -- parameters. Note that this is now a static error even if the
+ -- subprogram is not the main program (this is a change, in an
+ -- earlier version only the main program was affected, and the
+ -- check had to be done in the binder.
- if Nkind (Original_Node (Parent (P))) = N_Subprogram_Body
- and then Nkind (Parent (Parent (P))) = N_Compilation_Unit
- then
- Set_Has_Allocator (Current_Sem_Unit);
- end if;
+ if Nkind (P) = N_Subprogram_Body
+ and then Nkind (Parent (P)) = N_Compilation_Unit
+ and then No (Parameter_Specifications (Specification (P)))
+ then
+ Check_Restriction
+ (No_Standard_Allocators_After_Elaboration, N);
end if;
C := P;
===================================================================
@@ -0,0 +1,72 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . E L A B O R A T I O N _ A L L O C A T O R S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2014, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+package body System.Elaboration_Allocators is
+
+ Elaboration_In_Progress : Boolean;
+ pragma Atomic (Elaboration_In_Progress);
+ -- Flag to show if elaboration is active. We don't attempt to initialize
+ -- this because we want to be sure it gets reset if we are in a multiple
+ -- elaboration situation of some kind. Make it atomic to prevent race
+ -- conditions of any kind (not clearly necessary, but harmless!)
+
+ ------------------------------
+ -- Check_Standard_Allocator --
+ ------------------------------
+
+ procedure Check_Standard_Allocator is
+ begin
+ if not Elaboration_In_Progress then
+ raise Program_Error with
+ "standard allocator after elaboration is complete is not allowed "
+ & "(No_Standard_Allocators_After_Elaboration restriction active)";
+ end if;
+ end Check_Standard_Allocator;
+
+ -----------------------------
+ -- Mark_End_Of_Elaboration --
+ -----------------------------
+
+ procedure Mark_End_Of_Elaboration is
+ begin
+ Elaboration_In_Progress := False;
+ end Mark_End_Of_Elaboration;
+
+ -------------------------------
+ -- Mark_Start_Of_Elaboration --
+ -------------------------------
+
+ procedure Mark_Start_Of_Elaboration is
+ begin
+ Elaboration_In_Progress := True;
+ end Mark_Start_Of_Elaboration;
+
+end System.Elaboration_Allocators;
===================================================================
@@ -0,0 +1,57 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- S Y S T E M . E L A B O R A T I O N _ A L L O C A T O R S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2014, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides the interfaces for proper handling of restriction
+-- No_Standard_Allocators_After_Elaboration. It is used only by programs
+-- which use this restriction.
+
+package System.Elaboration_Allocators is
+ pragma Preelaborate;
+
+ procedure Mark_Start_Of_Elaboration;
+ -- Called right at the start of main elaboration if the program activates
+ -- restriction No_Standard_Allocators_After_Elaboration. We don't want to
+ -- rely on the normal elaboration mechanism for marking this event, since
+ -- that would require us to be sure to elaborate this first, which would
+ -- be awkward, and it is convenient to have this package be Preelaborate.
+
+ procedure Mark_End_Of_Elaboration;
+ -- Called when main elaboration is complete if the program has activated
+ -- restriction No_Standard_Allocators_After_Elaboration. This is the point
+ -- beyond which any standard allocator use will violate the restriction.
+
+ procedure Check_Standard_Allocator;
+ -- Called as part of every allocator in a program for which the restriction
+ -- No_Standard_Allocators_After_Elaboration is active. This will raise an
+ -- exception (Program_Error with an appropriate message) if it is called
+ -- after the call to Mark_End_Of_Elaboration.
+
+end System.Elaboration_Allocators;
===================================================================
@@ -518,6 +518,7 @@
s-direio$(objext) \
s-dmotpr$(objext) \
s-dsaser$(objext) \
+ s-elaall$(objext) \
s-excdeb$(objext) \
s-except$(objext) \
s-exctab$(objext) \
===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- Copyright (C) 1992-2014, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -923,22 +923,19 @@
-- Start of processing for Check_Consistent_Restrictions
begin
- -- A special test, if we have a main program, then if it has an
- -- allocator in the body, this is considered to be a violation of
- -- the restriction No_Allocators_After_Elaboration. We just mark
- -- this restriction and then the normal circuit will flag it.
+ -- We used to have a special test here:
- if Bind_Main_Program
- and then ALIs.Table (ALIs.First).Main_Program /= None
- and then not No_Main_Subprogram
- and then ALIs.Table (ALIs.First).Allocator_In_Body
- then
- Cumulative_Restrictions.Violated
- (No_Standard_Allocators_After_Elaboration) := True;
- ALIs.Table (ALIs.First).Restrictions.Violated
- (No_Standard_Allocators_After_Elaboration) := True;
- end if;
+ -- A special test, if we have a main program, then if it has an
+ -- allocator in the body, this is considered to be a violation of
+ -- the restriction No_Allocators_After_Elaboration. We just mark
+ -- this restriction and then the normal circuit will flag it.
+ -- But we don't do that any more, because in the final version of Ada
+ -- 2012, it is statically illegal to have an allocator in a library-
+ -- level subprogram, so we don't need this bind time test any more.
+ -- If we have a main program with parameters (which GNAT allows), then
+ -- allocators in that will be caught by the run-time check.
+
-- Loop through all restriction violations
for R in All_Restrictions loop