aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/sem_prag.adb
diff options
context:
space:
mode:
authorHristian Kirtchev <kirtchev@adacore.com>2017-01-09 12:03:27 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2017-01-09 13:03:27 +0100
commitf63d601b9629ffbf756c97dac2d4241ed43d9e4e (patch)
tree03d45e3343a5c67f1cd7ed05075ad1bd4a80c296 /gcc/ada/sem_prag.adb
parent01216d27de7de69ce1f09697e5f61ab414113824 (diff)
downloadgcc-f63d601b9629ffbf756c97dac2d4241ed43d9e4e.zip
gcc-f63d601b9629ffbf756c97dac2d4241ed43d9e4e.tar.gz
gcc-f63d601b9629ffbf756c97dac2d4241ed43d9e4e.tar.bz2
einfo.ads, einfo.adb: Remove uses of flags Has_Default_Init_Cond...
2017-01-09 Hristian Kirtchev <kirtchev@adacore.com> * einfo.ads, einfo.adb: Remove uses of flags Has_Default_Init_Cond, Is_Default_Init_Cond_Procedure, and Has_Inherited_Default_Init_Cond. Add uses of flags Has_Own_DIC, Is_DIC_Procedure, and Has_Inherited_DIC. (Default_Init_Cond_Procedure): Removed. (DIC_Procedure): New routine. (Has_Default_Init_Cond): Removed. (Has_DIC): New routine. (Has_Inheritable_Invariants): The attribute applies to the base type. (Has_Inherited_Default_Init_Cond): Removed. (Has_Inherited_DIC): New routine. (Has_Inherited_Invariants): The attribute applies to the base type. (Has_Own_DIC): New routine. (Has_Own_Invariants): The attribute applies to the base type. (Is_Default_Init_Cond_Procedure): Removed. (Is_DIC_Procedure): New routine. (Set_Default_Init_Cond_Procedure): Removed. (Set_DIC_Procedure): New routine. (Set_Has_Default_Init_Cond): Removed. (Set_Has_Inheritable_Invariants): The attribute applies to the base type. (Set_Has_Inherited_Default_Init_Cond): Removed. (Set_Has_Inherited_DIC): New routine. (Set_Has_Inherited_Invariants): The attribute applies to the base type. (Set_Has_Own_DIC): New routine. (Set_Has_Own_Invariants): The attribute applies to the base type. (Set_Is_Default_Init_Cond_Procedure): Removed. (Set_Is_DIC_Procedure): New routine. (Write_Entity_Flags): Update the output of all flags related to default initial condition. * exp_ch3.adb (Expand_N_Object_Declaration): Update the generation of the call to the DIC procedure. (Freeze_Type): Generate the body of the DIC procedure. * exp_ch7.adb (Build_Invariant_Procedure_Body): Replace all occurrences of Create_Append with Append_New_To. Do not generate an invariant procedure for a class-wide type. The generated body acts as a freeze action of the working type. (Build_Invariant_Procedure_Declaration): Do not generate an invariant procedure for a class-wide type. (Create_Append): Removed. * exp_util.adb: Add with and use clauses for Sem_Ch3, sem_ch6, sem_Ch12, Sem_Disp, and GNAT.HTable. Move the handling of class-wide pre/postcondition description and data structures from Sem_Prag. (Build_Class_Wide_Expression): Moved from Sem_Prag. (Build_DIC_Call): New routine. (Build_DIC_Procedure_Body): New routine. (Build_DIC_Procedure_Declaration): New routine. (Entity_Hash): Moved from Sem_Prag. (Find_DIC_Type): New routine. (Update_Primitives_Mapping): Reimplemented. (Update_Primitives_Mapping_Of_Types): New routine. * exp_util.ads (Build_Class_Wide_Expression): Moved from Sem_Prag. (Build_DIC_Call): New routine. (Build_DIC_Procedure_Body): New routine. (Build_DIC_Procedure_Declaration): New routine. (Update_Primitives_Mapping): Moved from Sem_Prag. (Update_Primitives_Mapping_Of_Types): New routine. * nlists.adb (Append_New): New routine. (Append_New_To): New routine. * nlists.ads (Append_New): New routine. (Append_New_To): New routine. * sem_ch3.adb (Analyze_Declarations): Do not generate the bodies of DIC procedures here. This is now done at the end of the visible declarations, private declarations, and at the freeze point of a type. (Analyze_Private_Extension_Declaration): A private extension inherits the DIC pragma of a parent type. (Analyze_Subtype_Declaration): No need to propagate invariant attributes to a subtype as those apply to the base type. (Build_Derived_Record_Type): No need to inherit invariants here as this is now done in Build_Derived_Type. (Build_Derived_Type): Inherit both the DIC pragma and invariants from a parent type. (Process_Full_View): Update the propagation of DIC attributes. (Propagate_Default_Init_Cond_Attributes): Removed. * sem_ch7.adb Add with and use clauses for Exp_Util. (Analyze_Package_Specification): Create the body of the DIC procedure at the end of the visible and private declarations. (Preserve_Full_Attributes): Propagate DIC attributes. * sem_ch9.adb (Analyze_Protected_Type_Declaration): Propagate DIC attributes. (Analyze_Task_Type_Declaration): Propagate DIC attributes. * sem_elab.adb (Check_A_Call): Update the call to Is_Nontrivial_Default_Init_Cond_Procedure. * sem_prag.adb Remove the with and use clauses for GNAT.HTable. Move the handling of class- wide pre/postcondition description and data structures to Exp_Util. (Analyze_Pragma): Create the declaration of the DIC procedure. There is no need to propagate invariant-related attributes at this point as this is done in Build_Invariant_Procedure_Declaration. (Build_Class_Wide_Expression): Moved to Exp_Util. (Entity_Hash): Moved to Exp_Util. (Update_Primitives_Mapping): Moved to Exp_Util. * sem_prag.ads (Build_Class_Wide_Expression): Moved to Exp_Util. (Update_Primitives_Mapping): Moved to Exp_Util. * sem_util.adb: Remove with and use clauses for Ghost and Sem_Ch13. (Build_Default_Init_Cond_Call): Removed. (Build_Default_Init_Cond_Procedure_Bodies): Removed. (Build_Default_Init_Cond_Procedure_Declaration): Removed. (Get_Views): Reimplemented. (Has_Full_Default_Initialization): Reimplement the section on DIC. (Inherit_Default_Init_Cond_Procedure): Removed. (Is_Nontrivial_Default_Init_Cond_Procedure): Removed. (Is_Nontrivial_DIC_Procedure): New routine. (Is_Verifiable_DIC_Pragma): New routine. (Propagate_DIC_Attributes): New routine. * sem_util.ads (Build_Default_Init_Cond_Call): Removed. (Build_Default_Init_Cond_Procedure_Bodies): Removed. (Build_Default_Init_Cond_Procedure_Declaration): Removed. (Inherit_Default_Init_Cond_Procedure): Removed. (Is_Nontrivial_Default_Init_Cond_Procedure): Removed. (Is_Nontrivial_DIC_Procedure): New routine. (Is_Verifiable_DIC_Pragma): New routine. (Propagate_DIC_Attributes): New routine. * sem_warn.adb (Is_OK_Fully_Initialized): Reimplement the section on DIC. * sinfo.ads, sinfo.adb: Add new attribute Expression_Copy along with usage in nodes. (Expression_Copy): New routine along with pragma Inline. (Set_Expression_Copy): New routine along with pragma Inline. From-SVN: r244224
Diffstat (limited to 'gcc/ada/sem_prag.adb')
-rw-r--r--gcc/ada/sem_prag.adb358
1 files changed, 12 insertions, 346 deletions
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 608acd0..b1a193f 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -89,8 +89,6 @@ with Urealp; use Urealp;
with Validsw; use Validsw;
with Warnsw; use Warnsw;
-with GNAT.HTable; use GNAT.HTable;
-
package body Sem_Prag is
----------------------------------------------
@@ -166,40 +164,6 @@ package body Sem_Prag is
Table_Increment => 100,
Table_Name => "Name_Externals");
- ---------------------------------------------------------
- -- Handling of inherited class-wide pre/postconditions --
- ---------------------------------------------------------
-
- -- Following AI12-0113, the expression for a class-wide condition is
- -- transformed for a subprogram that inherits it, by replacing calls
- -- to primitive operations of the original controlling type into the
- -- corresponding overriding operations of the derived type. The following
- -- hash table manages this mapping, and is expanded on demand whenever
- -- such inherited expression needs to be constructed.
-
- -- The mapping is also used to check whether an inherited operation has
- -- a condition that depends on overridden operations. For such an
- -- operation we must create a wrapper that is then treated as a normal
- -- overriding. In SPARK mode such operations are illegal.
-
- -- For a given root type there may be several type extensions with their
- -- own overriding operations, so at various times a given operation of
- -- the root will be mapped into different overridings. The root type is
- -- also mapped into the current type extension to indicate that its
- -- operations are mapped into the overriding operations of that current
- -- type extension.
-
- subtype Num_Primitives is Integer range 0 .. 510;
- function Entity_Hash (E : Entity_Id) return Num_Primitives;
-
- package Primitives_Mapping is new Gnat.HTable.Simple_Htable
- (Header_Num => Num_Primitives,
- Key => Entity_Id,
- Element => Entity_Id,
- No_element => Empty,
- Hash => Entity_Hash,
- Equal => "=");
-
-------------------------------------
-- Local Subprograms and Variables --
-------------------------------------
@@ -13784,7 +13748,7 @@ package body Sem_Prag is
-- pragma Default_Initial_Condition [ (null | boolean_EXPRESSION) ];
- when Pragma_Default_Initial_Condition => Default_Init_Cond : declare
+ when Pragma_Default_Initial_Condition => DIC : declare
Discard : Boolean;
Stmt : Node_Id;
Typ : Entity_Id;
@@ -13835,13 +13799,21 @@ package body Sem_Prag is
-- purposes of legality checks and removal of ignored Ghost code.
Mark_Pragma_As_Ghost (N, Typ);
- Set_Has_Default_Init_Cond (Typ);
- Set_Has_Inherited_Default_Init_Cond (Typ, False);
+
+ -- The pragma signals that the type defines its own DIC assertion
+ -- expression.
+
+ Set_Has_Own_DIC (Typ);
-- Chain the pragma on the rep item chain for further processing
Discard := Rep_Item_Too_Late (Typ, N, FOnly => True);
- end Default_Init_Cond;
+
+ -- Create the declaration of the procedure which verifies the
+ -- assertion expression of pragma DIC at runtime.
+
+ Build_DIC_Procedure_Declaration (Typ);
+ end DIC;
----------------------------------
-- Default_Scalar_Storage_Order --
@@ -16819,18 +16791,6 @@ package body Sem_Prag is
Typ : Entity_Id;
Typ_Arg : Node_Id;
- CRec_Typ : Entity_Id;
- -- The corresponding record type of Full_Typ
-
- Full_Base : Entity_Id;
- -- The base type of Full_Typ
-
- Full_Typ : Entity_Id;
- -- The full view of Typ
-
- Priv_Typ : Entity_Id;
- -- The partial view of Typ
-
begin
GNAT_Pragma;
Check_At_Least_N_Arguments (2);
@@ -16924,16 +16884,6 @@ package body Sem_Prag is
Set_Has_Inheritable_Invariants (Typ);
end if;
- Get_Views (Typ, Priv_Typ, Full_Typ, Full_Base, CRec_Typ);
-
- -- Propagate invariant-related attributes to all views of the type
- -- and any additional types that may have been created.
-
- Propagate_Invariant_Attributes (Priv_Typ, From_Typ => Typ);
- Propagate_Invariant_Attributes (Full_Typ, From_Typ => Typ);
- Propagate_Invariant_Attributes (Full_Base, From_Typ => Typ);
- Propagate_Invariant_Attributes (CRec_Typ, From_Typ => Typ);
-
-- Chain the pragma on to the rep item chain, for processing when
-- the type is frozen.
@@ -26766,140 +26716,6 @@ package body Sem_Prag is
return False;
end Appears_In;
- ---------------------------------
- -- Build_Class_Wide_Expression --
- ---------------------------------
-
- procedure Build_Class_Wide_Expression
- (Prag : Node_Id;
- Subp : Entity_Id;
- Par_Subp : Entity_Id;
- Adjust_Sloc : Boolean)
- is
- function Replace_Entity (N : Node_Id) return Traverse_Result;
- -- Replace reference to formal of inherited operation or to primitive
- -- operation of root type, with corresponding entity for derived type,
- -- when constructing the class-wide condition of an overriding
- -- subprogram.
-
- --------------------
- -- Replace_Entity --
- --------------------
-
- function Replace_Entity (N : Node_Id) return Traverse_Result is
- New_E : Entity_Id;
-
- begin
- if Adjust_Sloc then
- Adjust_Inherited_Pragma_Sloc (N);
- end if;
-
- if Nkind (N) = N_Identifier
- and then Present (Entity (N))
- and then
- (Is_Formal (Entity (N)) or else Is_Subprogram (Entity (N)))
- and then
- (Nkind (Parent (N)) /= N_Attribute_Reference
- or else Attribute_Name (Parent (N)) /= Name_Class)
- then
- -- The replacement does not apply to dispatching calls within the
- -- condition, but only to calls whose static tag is that of the
- -- parent type.
-
- if Is_Subprogram (Entity (N))
- and then Nkind (Parent (N)) = N_Function_Call
- and then Present (Controlling_Argument (Parent (N)))
- then
- return OK;
- end if;
-
- -- Determine whether entity has a renaming
-
- New_E := Primitives_Mapping.Get (Entity (N));
-
- if Present (New_E) then
- Rewrite (N, New_Occurrence_Of (New_E, Sloc (N)));
- end if;
-
- -- Check that there are no calls left to abstract operations if
- -- the current subprogram is not abstract.
-
- if Nkind (Parent (N)) = N_Function_Call
- and then N = Name (Parent (N))
- then
- if not Is_Abstract_Subprogram (Subp)
- and then Is_Abstract_Subprogram (Entity (N))
- then
- Error_Msg_Sloc := Sloc (Current_Scope);
- Error_Msg_NE
- ("cannot call abstract subprogram in inherited condition "
- & "for&#", N, Current_Scope);
-
- -- In SPARK mode, reject an inherited condition for an
- -- inherited operation if it contains a call to an overriding
- -- operation, because this implies that the pre/postcondition
- -- of the inherited operation have changed silently.
-
- elsif SPARK_Mode = On
- and then Warn_On_Suspicious_Contract
- and then Present (Alias (Subp))
- and then Present (New_E)
- and then Comes_From_Source (New_E)
- then
- Error_Msg_N
- ("cannot modify inherited condition (SPARK RM 6.1.1(1))",
- Parent (Subp));
- Error_Msg_Sloc := Sloc (New_E);
- Error_Msg_Node_2 := Subp;
- Error_Msg_NE
- ("\overriding of&# forces overriding of&",
- Parent (Subp), New_E);
- end if;
- end if;
-
- -- Update type of function call node, which should be the same as
- -- the function's return type.
-
- if Is_Subprogram (Entity (N))
- and then Nkind (Parent (N)) = N_Function_Call
- then
- Set_Etype (Parent (N), Etype (Entity (N)));
- end if;
-
- -- The whole expression will be reanalyzed
-
- elsif Nkind (N) in N_Has_Etype then
- Set_Analyzed (N, False);
- end if;
-
- return OK;
- end Replace_Entity;
-
- procedure Replace_Condition_Entities is
- new Traverse_Proc (Replace_Entity);
-
- -- Local variables
-
- Par_Formal : Entity_Id;
- Subp_Formal : Entity_Id;
-
- -- Start of processing for Build_Class_Wide_Expression
-
- begin
- -- Add mapping from old formals to new formals
-
- Par_Formal := First_Formal (Par_Subp);
- Subp_Formal := First_Formal (Subp);
-
- while Present (Par_Formal) and then Present (Subp_Formal) loop
- Primitives_Mapping.Set (Par_Formal, Subp_Formal);
- Next_Formal (Par_Formal);
- Next_Formal (Subp_Formal);
- end loop;
-
- Replace_Condition_Entities (Prag);
- end Build_Class_Wide_Expression;
-
-----------------------------------
-- Build_Pragma_Check_Equivalent --
-----------------------------------
@@ -27930,15 +27746,6 @@ package body Sem_Prag is
end if;
end Duplication_Error;
- -----------------
- -- Entity_Hash --
- -----------------
-
- function Entity_Hash (E : Entity_Id) return Num_Primitives is
- begin
- return Num_Primitives (E mod 511);
- end Entity_Hash;
-
------------------------------
-- Find_Encapsulating_State --
------------------------------
@@ -29780,145 +29587,4 @@ package body Sem_Prag is
return Empty;
end Test_Case_Arg;
- -------------------------------
- -- Update_Primitives_Mapping --
- -------------------------------
-
- procedure Update_Primitives_Mapping
- (Inher_Id : Entity_Id;
- Subp_Id : Entity_Id)
- is
- function Overridden_Ancestor (S : Entity_Id) return Entity_Id;
- -- Locate the primitive operation with the name of S whose controlling
- -- type is the dispatching type of Inher_Id.
-
- -------------------------
- -- Overridden_Ancestor --
- -------------------------
-
- function Overridden_Ancestor (S : Entity_Id) return Entity_Id is
- Par : constant Entity_Id := Find_Dispatching_Type (Inher_Id);
- Anc : Entity_Id;
-
- begin
- Anc := S;
-
- -- Locate the ancestor subprogram with the proper controlling type
-
- while Present (Overridden_Operation (Anc)) loop
- Anc := Overridden_Operation (Anc);
- exit when Find_Dispatching_Type (Anc) = Par;
- end loop;
-
- return Anc;
- end Overridden_Ancestor;
-
- -- Local variables
-
- Old_Typ : constant Entity_Id := Find_Dispatching_Type (Inher_Id);
- Typ : constant Entity_Id := Find_Dispatching_Type (Subp_Id);
- Decl : Node_Id;
- Old_Elmt : Elmt_Id;
- Old_Prim : Entity_Id;
- Prim : Entity_Id;
-
- -- Start of processing for Update_Primitives_Mapping
-
- begin
- -- If the types are already in the map, it has been previously built for
- -- some other overriding primitive.
-
- if Primitives_Mapping.Get (Old_Typ) = Typ then
- return;
-
- else
- -- Initialize new mapping with the primitive operations
-
- Decl := First (List_Containing (Unit_Declaration_Node (Subp_Id)));
-
- -- Look for primitive operations of the current type that have
- -- overridden an operation of the type related to the original
- -- class-wide precondition. There may be several intermediate
- -- overridings between them.
-
- while Present (Decl) loop
- if Nkind_In (Decl, N_Abstract_Subprogram_Declaration,
- N_Subprogram_Declaration)
- then
- Prim := Defining_Entity (Decl);
-
- if Is_Subprogram (Prim)
- and then Present (Overridden_Operation (Prim))
- and then Find_Dispatching_Type (Prim) = Typ
- then
- Old_Prim := Overridden_Ancestor (Prim);
-
- Primitives_Mapping.Set (Old_Prim, Prim);
- end if;
- end if;
-
- Next (Decl);
- end loop;
-
- -- Now examine inherited operations. these do not override, but have
- -- an alias, which is the entity used in a call. That alias may be
- -- inherited or come from source, in which case it may override an
- -- earlier operation. We only need to examine inherited functions,
- -- that can appear within the inherited expression.
-
- Prim := First_Entity (Scope (Subp_Id));
- while Present (Prim) loop
- if not Comes_From_Source (Prim)
- and then Ekind (Prim) = E_Function
- and then Present (Alias (Prim))
- then
- Old_Prim := Alias (Prim);
-
- if Comes_From_Source (Old_Prim) then
- Old_Prim := Overridden_Ancestor (Old_Prim);
-
- else
- while Present (Alias (Old_Prim))
- and then Scope (Old_Prim) /= Scope (Inher_Id)
- loop
- Old_Prim := Alias (Old_Prim);
-
- if Comes_From_Source (Old_Prim) then
- Old_Prim := Overridden_Ancestor (Old_Prim);
- exit;
- end if;
- end loop;
- end if;
-
- Primitives_Mapping.Set (Old_Prim, Prim);
- end if;
-
- Next_Entity (Prim);
- end loop;
-
- -- If the parent operation is an interface operation, the overriding
- -- indicator is not present. Instead, we get from the interface
- -- operation the primitive of the current type that implements it.
-
- if Is_Interface (Old_Typ) then
- Old_Elmt := First_Elmt (Collect_Primitive_Operations (Old_Typ));
- while Present (Old_Elmt) loop
- Old_Prim := Node (Old_Elmt);
- Prim := Find_Primitive_Covering_Interface (Typ, Old_Prim);
-
- if Present (Prim) then
- Primitives_Mapping.Set (Old_Prim, Prim);
- end if;
-
- Next_Elmt (Old_Elmt);
- end loop;
- end if;
- end if;
-
- -- Map the types themselves, so that the process is not repeated for
- -- other overriding primitives.
-
- Primitives_Mapping.Set (Old_Typ, Typ);
- end Update_Primitives_Mapping;
-
end Sem_Prag;