aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorRobert Dewar <dewar@adacore.com>2010-10-26 13:12:34 +0000
committerArnaud Charlet <charlet@gcc.gnu.org>2010-10-26 15:12:34 +0200
commitf2264ac2cd6325b96d5a742ce72159a011636f38 (patch)
tree8a6ecde825359b408b09247b4efe229b7d9826f1 /gcc/ada
parent1ce9dff334e66750cfc2a42509c8bed0d7a16f63 (diff)
downloadgcc-f2264ac2cd6325b96d5a742ce72159a011636f38.zip
gcc-f2264ac2cd6325b96d5a742ce72159a011636f38.tar.gz
gcc-f2264ac2cd6325b96d5a742ce72159a011636f38.tar.bz2
sem_ch13.adb (Build_Invariant_Procedure): New calling sequence.
2010-10-26 Robert Dewar <dewar@adacore.com> * sem_ch13.adb (Build_Invariant_Procedure): New calling sequence. (Build_Invariant_Procedure): Properly handle analysis of invariant expression with proper end-of-visible-decls visibility. * sem_ch13.ads (Build_Invariant_Procedure): Changed calling sequence. * sem_ch3.adb (Process_Full_View): Don't build invariant procedure (too late). (Analyze_Private_Extension_Declaration): Propagate invariant flags. * sem_ch7.adb (Analyze_Package_Specification): Build invariant procedures. From-SVN: r165960
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog12
-rw-r--r--gcc/ada/sem_ch13.adb77
-rw-r--r--gcc/ada/sem_ch13.ads21
-rw-r--r--gcc/ada/sem_ch3.adb60
-rw-r--r--gcc/ada/sem_ch7.adb12
5 files changed, 101 insertions, 81 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 47a6abc..b5ecd08 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,15 @@
+2010-10-26 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch13.adb (Build_Invariant_Procedure): New calling sequence.
+ (Build_Invariant_Procedure): Properly handle analysis of invariant
+ expression with proper end-of-visible-decls visibility.
+ * sem_ch13.ads (Build_Invariant_Procedure): Changed calling sequence.
+ * sem_ch3.adb (Process_Full_View): Don't build invariant procedure
+ (too late).
+ (Analyze_Private_Extension_Declaration): Propagate invariant flags.
+ * sem_ch7.adb (Analyze_Package_Specification): Build invariant
+ procedures.
+
2010-10-26 Vincent Celier <celier@adacore.com>
* opt.ads (Old_Checksums, Old_Old_Checksums): New Boolean flags,
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 488a4d7..d2e8958 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -3549,15 +3549,16 @@ package body Sem_Ch13 is
-- ...
-- end typInvariant;
- procedure Build_Invariant_Procedure
- (Typ : Entity_Id;
- PDecl : out Node_Id;
- PBody : out Node_Id)
- is
+ procedure Build_Invariant_Procedure (Typ : Entity_Id; N : Node_Id) is
Loc : constant Source_Ptr := Sloc (Typ);
Stmts : List_Id;
Spec : Node_Id;
SId : Entity_Id;
+ PDecl : Node_Id;
+ PBody : Node_Id;
+
+ Visible_Decls : constant List_Id := Visible_Declarations (N);
+ Private_Decls : constant List_Id := Private_Declarations (N);
procedure Add_Invariants (T : Entity_Id; Inherit : Boolean);
-- Appends statements to Stmts for any invariants in the rep item chain
@@ -3570,6 +3571,10 @@ package body Sem_Ch13 is
Object_Name : constant Name_Id := New_Internal_Name ('I');
-- Name for argument of invariant procedure
+ Object_Entity : constant Node_Id :=
+ Make_Defining_Identifier (Loc, Object_Name);
+ -- The procedure declaration entity for the argument
+
--------------------
-- Add_Invariants --
--------------------
@@ -3594,7 +3599,10 @@ package body Sem_Ch13 is
new Replace_Type_References_Generic (Replace_Type_Reference);
-- Traverse an expression replacing all occurrences of the subtype
-- name with appropriate references to the object that is the formal
- -- parameter of the predicate function.
+ -- parameter of the predicate function. Note that we must ensure
+ -- that the type and entity information is properly set in the
+ -- replacement node, since we will do a Preanalyze call of this
+ -- expression without proper visibility of the procedure argument.
----------------------------
-- Replace_Type_Reference --
@@ -3616,12 +3624,15 @@ package body Sem_Ch13 is
Make_Identifier (Loc,
Chars => Object_Name)));
+ Set_Entity (Expression (N), Object_Entity);
+ Set_Etype (Expression (N), Typ);
+
-- Invariant, replace with obj
else
- Rewrite (N,
- Make_Identifier (Loc,
- Chars => Object_Name));
+ Rewrite (N, Make_Identifier (Loc, Chars => Object_Name));
+ Set_Entity (N, Object_Entity);
+ Set_Etype (N, Typ);
end if;
end Replace_Type_Reference;
@@ -3668,13 +3679,20 @@ package body Sem_Ch13 is
Replace_Type_References (Exp, Chars (T));
+ -- Now we need to preanalyze the expression to properly capture
+ -- the visibility in the visible part. The expression will not
+ -- be analyzed for real until the body is analyzed, but that is
+ -- at the end of the private part and has the wrong visibility.
+
+ Set_Parent (Exp, N);
+ Preanalyze_Spec_Expression (Exp, Standard_Boolean);
+
-- Build first two arguments for Check pragma
Assoc := New_List (
Make_Pragma_Argument_Association (Loc,
Expression =>
- Make_Identifier (Loc,
- Chars => Name_Invariant)),
+ Make_Identifier (Loc, Chars => Name_Invariant)),
Make_Pragma_Argument_Association (Loc,
Expression => Exp));
@@ -3705,8 +3723,7 @@ package body Sem_Ch13 is
Append_To (Stmts,
Make_Pragma (Loc,
Pragma_Identifier =>
- Make_Identifier (Loc,
- Chars => Name_Check),
+ Make_Identifier (Loc, Chars => Name_Check),
Pragma_Argument_Associations => Assoc));
-- If Inherited case and option enabled, output info msg. Note
@@ -3731,6 +3748,7 @@ package body Sem_Ch13 is
Stmts := No_List;
PDecl := Empty;
PBody := Empty;
+ Set_Etype (Object_Entity, Typ);
-- Add invariants for the current type
@@ -3766,7 +3784,6 @@ package body Sem_Ch13 is
-- Build procedure declaration
- pragma Assert (Has_Invariants (Typ));
SId :=
Make_Defining_Identifier (Loc,
Chars => New_External_Name (Chars (Typ), "Invariant"));
@@ -3778,15 +3795,10 @@ package body Sem_Ch13 is
Defining_Unit_Name => SId,
Parameter_Specifications => New_List (
Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars => Object_Name),
- Parameter_Type =>
- New_Occurrence_Of (Typ, Loc))));
+ Defining_Identifier => Object_Entity,
+ Parameter_Type => New_Occurrence_Of (Typ, Loc))));
- PDecl :=
- Make_Subprogram_Declaration (Loc,
- Specification => Spec);
+ PDecl := Make_Subprogram_Declaration (Loc, Specification => Spec);
-- Build procedure body
@@ -3812,6 +3824,27 @@ package body Sem_Ch13 is
Handled_Statement_Sequence =>
Make_Handled_Sequence_Of_Statements (Loc,
Statements => Stmts));
+
+ -- Insert procedure declaration and spec at the appropriate points.
+ -- Skip this if there are no private declarations (that's an error
+ -- that will be diagnosed elsewhere, and there is no point in having
+ -- an invariant procedure set if the full declaration is missing).
+
+ if Present (Private_Decls) then
+
+ -- The spec goes at the end of visible declarations, but they have
+ -- already been analyzed, so we need to explicitly do the analyze.
+
+ Append_To (Visible_Decls, PDecl);
+ Analyze (PDecl);
+
+ -- The body goes at the end of the private declarations, which we
+ -- have not analyzed yet, so we do not need to perform an explicit
+ -- analyze call. We skip this if there are no private declarations
+ -- (this is an error that will be caught elsewhere);
+
+ Append_To (Private_Decls, PBody);
+ end if;
end if;
end Build_Invariant_Procedure;
diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads
index 8d0245d..1c51a27 100644
--- a/gcc/ada/sem_ch13.ads
+++ b/gcc/ada/sem_ch13.ads
@@ -52,17 +52,16 @@ package Sem_Ch13 is
-- order is specified and there is at least one component clause. Adjusts
-- component positions according to either Ada 95 or Ada 2005 (AI-133).
- procedure Build_Invariant_Procedure
- (Typ : Entity_Id;
- PDecl : out Node_Id;
- PBody : out Node_Id);
- -- If Typ has Invariants (indicated by Has_Invariants being set for Typ,
- -- indicating the presence of pragma Invariant entries on the rep chain,
- -- note that Invariant aspects are converted to pragma Invariant), then
- -- this procedure builds the spec and body for the corresponding Invariant
- -- procedure, returning themn in PDecl and PBody. Invariant_Procedure is
- -- set for Typ. In some error situations no procedure is built, in which
- -- case PDecl/PBody are empty on return.
+ procedure Build_Invariant_Procedure (Typ : Entity_Id; N : Node_Id);
+ -- Typ is a private type with invariants (indicated by Has_Invariants being
+ -- set for Typ, indicating the presence of pragma Invariant entries on the
+ -- rep chain, note that Invariant aspects have already been converted to
+ -- pragma Invariant), then this procedure builds the spec and body for the
+ -- corresponding Invariant procedure, inserting them at appropriate points
+ -- in the package specification N. Invariant_Procedure is set for Typ. Note
+ -- that this procedure is called at the end of processing the declarations
+ -- in the visible part (i.e. the right point for visibility analysis of
+ -- the invariant expression).
procedure Check_Record_Representation_Clause (N : Node_Id);
-- This procedure completes the analysis of a record representation clause
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 62aee52..60caeb9 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -3731,6 +3731,15 @@ package body Sem_Ch3 is
Build_Derived_Record_Type (N, Parent_Type, T);
+ -- Propagate inherited invariant information. The new type has
+ -- invariants, if the parent type has inheritable invariants,
+ -- and these invariants can in turn be inherited.
+
+ if Has_Inheritable_Invariants (Parent_Type) then
+ Set_Has_Inheritable_Invariants (T);
+ Set_Has_Invariants (T);
+ end if;
+
-- Ada 2005 (AI-443): Synchronized private extension or a rewritten
-- synchronized formal derived type.
@@ -17439,58 +17448,15 @@ package body Sem_Ch3 is
Set_Has_Specified_Stream_Output (Full_T);
end if;
- -- Deal with invariants
+ -- Propagate invariants to full type
- if Has_Invariants (Full_T)
- or else
- Has_Invariants (Priv_T)
- then
+ if Has_Invariants (Priv_T) then
Set_Has_Invariants (Full_T);
- Set_Has_Invariants (Priv_T);
+ Set_Invariant_Procedure (Full_T, Invariant_Procedure (Priv_T));
end if;
- if Has_Inheritable_Invariants (Full_T)
- or else
- Has_Inheritable_Invariants (Priv_T)
- then
+ if Has_Inheritable_Invariants (Priv_T) then
Set_Has_Inheritable_Invariants (Full_T);
- Set_Has_Inheritable_Invariants (Priv_T);
- end if;
-
- -- This is where we build the invariant procedure if needed
-
- if Has_Invariants (Priv_T) then
- declare
- PDecl : Entity_Id;
- PBody : Entity_Id;
- Packg : constant Node_Id := Declaration_Node (Scope (Priv_T));
-
- begin
- Build_Invariant_Procedure (Full_T, PDecl, PBody);
-
- -- Error defense, normally these should be set
-
- if Present (PDecl) and then Present (PBody) then
-
- -- Spec goes at the end of the public part of the package.
- -- That's behind us, so we have to manually analyze the
- -- inserted spec.
-
- Append_To (Visible_Declarations (Packg), PDecl);
- Analyze (PDecl);
-
- -- Body goes at the end of the private part of the package.
- -- That's ahead of us so it will get analyzed later on when
- -- we come to it.
-
- Append_To (Private_Declarations (Packg), PBody);
-
- -- Copy Invariant procedure to private declaration
-
- Set_Invariant_Procedure (Priv_T, Invariant_Procedure (Full_T));
- Set_Has_Invariants (Priv_T);
- end if;
- end;
end if;
-- Propagate predicates to full type
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index e9f9fac..b769357 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -1128,16 +1128,26 @@ package body Sem_Ch7 is
Analyze_Declarations (Vis_Decls);
end if;
- -- Verify that incomplete types have received full declarations
+ -- Verify that incomplete types have received full declarations and
+ -- also build invariant procedures for any types with invariants.
E := First_Entity (Id);
while Present (E) loop
+
+ -- Check on incomplete types
+
if Ekind (E) = E_Incomplete_Type
and then No (Full_View (E))
then
Error_Msg_N ("no declaration in visible part for incomplete}", E);
end if;
+ -- Build invariant procedures
+
+ if Is_Type (E) and then Has_Invariants (E) then
+ Build_Invariant_Procedure (E, N);
+ end if;
+
Next_Entity (E);
end loop;