summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch3.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-31 09:33:10 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2014-07-31 09:33:10 +0000
commit0c2bde47dd764f1f844e34f3f496e3ef838c2875 (patch)
tree0b095b8f157d221a4c09861718672792dae5468a /gcc/ada/exp_ch3.adb
parent8c3766fd997d5ee379e11cc0d888777bda3992e6 (diff)
downloadgcc-0c2bde47dd764f1f844e34f3f496e3ef838c2875.tar.gz
2014-07-31 Ed Schonberg <schonberg@adacore.com>
* sem_ch13.adb (Build_Invariant_Procedure): If body of procedure is already present, nothing to do. * exp_ch3.adb (Build_Component_Invariant_Call): For an access component, check whether the access type has an invariant before checking the designated type. (Build_Record_Invariant_Proc): Change suffix of generated name to prevent ambiguity when record type has invariants in addition to those of components, and two subprograms are constructed. Consistent with handling of array types. (Insert_Component_Invariant_Checks): Build invariant procedure body when one has not been created yet, in the case of composite types that are completions and whose full declarations carry invariants. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213322 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_ch3.adb')
-rw-r--r--gcc/ada/exp_ch3.adb46
1 files changed, 40 insertions, 6 deletions
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 6533db22727..520f9329bd3 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -56,6 +56,7 @@ with Sem_Cat; use Sem_Cat;
with Sem_Ch3; use Sem_Ch3;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Ch13; use Sem_Ch13;
with Sem_Disp; use Sem_Disp;
with Sem_Eval; use Sem_Eval;
with Sem_Mech; use Sem_Mech;
@@ -3704,8 +3705,21 @@ package body Exp_Ch3 is
Selector_Name => New_Occurrence_Of (Comp, Loc));
if Is_Access_Type (Typ) then
- Sel_Comp := Make_Explicit_Dereference (Loc, Sel_Comp);
- Typ := Designated_Type (Typ);
+
+ -- If the access component designates a type with an invariant,
+ -- the check applies to the designated object. The access type
+ -- itself may have an invariant, in which case it applies to the
+ -- access value directly.
+
+ -- Note: we are assuming that invariants will not occur on both
+ -- the access type and the type that it designates. This is not
+ -- really justified but it is hard to imagine that this case will
+ -- ever cause trouble ???
+
+ if not (Has_Invariants (Typ)) then
+ Sel_Comp := Make_Explicit_Dereference (Loc, Sel_Comp);
+ Typ := Designated_Type (Typ);
+ end if;
end if;
Call :=
@@ -3822,9 +3836,14 @@ package body Exp_Ch3 is
return Empty;
end if;
+ -- The name of the invariant procedure reflects the fact that the
+ -- checks correspond to invariants on the component types. The
+ -- record type itself may have invariants that will create a separate
+ -- procedure whose name carries the Invariant suffix.
+
Proc_Id :=
Make_Defining_Identifier (Loc,
- Chars => New_External_Name (Chars (R_Type), "Invariant"));
+ Chars => New_External_Name (Chars (R_Type), "CInvariant"));
Proc_Body :=
Make_Subprogram_Body (Loc,
@@ -8045,14 +8064,15 @@ package body Exp_Ch3 is
else
- -- Find already created invariant body, insert body of component
- -- invariant proc in it, and add call after other checks.
+ -- Find already created invariant subprogram, insert body of
+ -- component invariant proc in its body, and add call after
+ -- other checks.
declare
Bod : Node_Id;
Inv_Id : constant Entity_Id := Invariant_Procedure (Typ);
Call : constant Node_Id :=
- Make_Procedure_Call_Statement (Loc,
+ Make_Procedure_Call_Statement (Sloc (N),
Name => New_Occurrence_Of (Proc_Id, Loc),
Parameter_Associations =>
New_List
@@ -8070,8 +8090,22 @@ package body Exp_Ch3 is
Next (Bod);
end loop;
+ -- If the body is not found, it is the case of an invariant
+ -- appearing on a full declaration in a private part, in
+ -- which case the type has been frozen but the invariant
+ -- procedure for the composite type not created yet. Create
+ -- body now.
+
+ if No (Bod) then
+ Build_Invariant_Procedure (Typ, Parent (Current_Scope));
+ Bod := Unit_Declaration_Node
+ (Corresponding_Body (Unit_Declaration_Node (Inv_Id)));
+ end if;
+
Append_To (Declarations (Bod), Proc);
Append_To (Statements (Handled_Statement_Sequence (Bod)), Call);
+ Analyze (Proc);
+ Analyze (Call);
end;
end if;
end if;