aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ada/ChangeLog25
-rw-r--r--gcc/ada/exp_ch7.adb15
-rw-r--r--gcc/ada/exp_util.adb95
-rw-r--r--gcc/ada/exp_util.ads9
-rw-r--r--gcc/ada/sem_res.adb13
5 files changed, 113 insertions, 44 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 904c9cc..f42c041 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,28 @@
+2012-04-02 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * exp_ch7.adb (Process_Declarations): Detect a case where
+ a source object was initialized by another source object,
+ but the expression was rewritten as a class-wide conversion
+ of Ada.Tags.Displace.
+ * exp_util.adb (Initialized_By_Ctrl_Function): Removed.
+ (Is_Controlled_Function_Call): New routine.
+ (Is_Displacement_Of_Ctrl_Function_Result): Removed.
+ (Is_Displacement_Of_Object_Or_Function_Result): New routine.
+ (Is_Source_Object): New routine.
+ (Requires_Cleanup_Actions): Detect a case where a source object was
+ initialized by another source object, but the expression was rewritten
+ as a class-wide conversion of Ada.Tags.Displace.
+ * exp_util.ads (Is_Displacement_Of_Ctrl_Function_Result): Removed.
+ (Is_Displacement_Of_Object_Or_Function_Result): New routine.
+
+2012-04-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_res.adb (Resolve_Call): A call to an expression function
+ does not freeze if it appears in a different scope from the
+ expression function itself. Such calls appear in the generated
+ bodies of other expression functions, or in pre/postconditions
+ of subsequent subprograms.
+
2012-04-02 Yannick Moy <moy@adacore.com>
* lib-xref-alfa.adb: Code clean up.
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 525bae7..f8730f3 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -1917,16 +1917,17 @@ package body Exp_Ch7 is
Processing_Actions (Has_No_Init => True);
-- Detect a case where a source object has been initialized by
- -- a controlled function call which was later rewritten as a
- -- class-wide conversion of Ada.Tags.Displace.
+ -- a controlled function call or another object which was later
+ -- rewritten as a class-wide conversion of Ada.Tags.Displace.
- -- Obj : Class_Wide_Type := Function_Call (...);
+ -- Obj1 : CW_Type := Src_Obj;
+ -- Obj2 : CW_Type := Function_Call (...);
- -- Temp : ... := Function_Call (...)'reference;
- -- Obj : Class_Wide_Type renames
- -- (... Ada.Tags.Displace (Temp));
+ -- Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
+ -- Tmp : ... := Function_Call (...)'reference;
+ -- Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
- elsif Is_Displacement_Of_Ctrl_Function_Result (Obj_Id) then
+ elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
Processing_Actions (Has_No_Init => True);
end if;
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 335ba10..b43bd16 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -3940,27 +3940,30 @@ package body Exp_Util is
return True;
end Is_All_Null_Statements;
- ---------------------------------------------
- -- Is_Displacement_Of_Ctrl_Function_Result --
- ---------------------------------------------
+ --------------------------------------------------
+ -- Is_Displacement_Of_Object_Or_Function_Result --
+ --------------------------------------------------
- function Is_Displacement_Of_Ctrl_Function_Result
+ function Is_Displacement_Of_Object_Or_Function_Result
(Obj_Id : Entity_Id) return Boolean
is
- function Initialized_By_Ctrl_Function (N : Node_Id) return Boolean;
- -- Determine whether object declaration N is initialized by a controlled
- -- function call.
+ function Is_Controlled_Function_Call (N : Node_Id) return Boolean;
+ -- Determine whether a particular node denotes a controlled function
+ -- call.
function Is_Displace_Call (N : Node_Id) return Boolean;
-- Determine whether a particular node is a call to Ada.Tags.Displace.
-- The call might be nested within other actions such as conversions.
- ----------------------------------
- -- Initialized_By_Ctrl_Function --
- ----------------------------------
+ function Is_Source_Object (N : Node_Id) return Boolean;
+ -- Determine whether a particular node denotes a source object
+
+ ---------------------------------
+ -- Is_Controlled_Function_Call --
+ ---------------------------------
- function Initialized_By_Ctrl_Function (N : Node_Id) return Boolean is
- Expr : Node_Id := Original_Node (Expression (N));
+ function Is_Controlled_Function_Call (N : Node_Id) return Boolean is
+ Expr : Node_Id := Original_Node (N);
begin
if Nkind (Expr) = N_Function_Call then
@@ -3977,7 +3980,7 @@ package body Exp_Util is
Nkind_In (Expr, N_Expanded_Name, N_Identifier)
and then Ekind (Entity (Expr)) = E_Function
and then Needs_Finalization (Etype (Entity (Expr)));
- end Initialized_By_Ctrl_Function;
+ end Is_Controlled_Function_Call;
----------------------
-- Is_Displace_Call --
@@ -4004,39 +4007,66 @@ package body Exp_Util is
end loop;
return
- Nkind (Call) = N_Function_Call
+ Present (Call)
+ and then Nkind (Call) = N_Function_Call
and then Is_RTE (Entity (Name (Call)), RE_Displace);
end Is_Displace_Call;
+ ----------------------
+ -- Is_Source_Object --
+ ----------------------
+
+ function Is_Source_Object (N : Node_Id) return Boolean is
+ begin
+ return
+ Present (N)
+ and then Nkind (N) in N_Has_Entity
+ and then Is_Object (Entity (N))
+ and then Comes_From_Source (N);
+ end Is_Source_Object;
+
-- Local variables
Decl : constant Node_Id := Parent (Obj_Id);
Obj_Typ : constant Entity_Id := Base_Type (Etype (Obj_Id));
Orig_Decl : constant Node_Id := Original_Node (Decl);
- -- Start of processing for Is_Displacement_Of_Ctrl_Function_Result
+ -- Start of processing for Is_Displacement_Of_Object_Or_Function_Result
begin
- -- Detect the following case:
+ -- Case 1:
- -- Obj : Class_Wide_Type := Function_Call (...);
+ -- Obj : CW_Type := Function_Call (...);
- -- which is rewritten into:
+ -- rewritten into:
- -- Temp : ... := Function_Call (...)'reference;
- -- Obj : Class_Wide_Type renames (... Ada.Tags.Displace (Temp));
+ -- Tmp : ... := Function_Call (...)'reference;
+ -- Obj : CW_Type renames (... Ada.Tags.Displace (Tmp));
- -- when the return type of the function and the class-wide type require
+ -- where the return type of the function and the class-wide type require
+ -- dispatch table pointer displacement.
+
+ -- Case 2:
+
+ -- Obj : CW_Type := Src_Obj;
+
+ -- rewritten into:
+
+ -- Obj : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
+
+ -- where the type of the source object and the class-wide type require
-- dispatch table pointer displacement.
return
Nkind (Decl) = N_Object_Renaming_Declaration
and then Nkind (Orig_Decl) = N_Object_Declaration
and then Comes_From_Source (Orig_Decl)
- and then Initialized_By_Ctrl_Function (Orig_Decl)
and then Is_Class_Wide_Type (Obj_Typ)
- and then Is_Displace_Call (Renamed_Object (Obj_Id));
- end Is_Displacement_Of_Ctrl_Function_Result;
+ and then Is_Displace_Call (Renamed_Object (Obj_Id))
+ and then
+ (Is_Controlled_Function_Call (Expression (Orig_Decl))
+ or else Is_Source_Object (Expression (Orig_Decl)));
+ end Is_Displacement_Of_Object_Or_Function_Result;
------------------------------
-- Is_Finalizable_Transient --
@@ -7189,17 +7219,18 @@ package body Exp_Util is
then
return True;
- -- Detect a case where a source object has been initialized by a
- -- controlled function call which was later rewritten as a class-
- -- wide conversion of Ada.Tags.Displace.
+ -- Detect a case where a source object has been initialized by
+ -- a controlled function call or another object which was later
+ -- rewritten as a class-wide conversion of Ada.Tags.Displace.
- -- Obj : Class_Wide_Type := Function_Call (...);
+ -- Obj1 : CW_Type := Src_Obj;
+ -- Obj2 : CW_Type := Function_Call (...);
- -- Temp : ... := Function_Call (...)'reference;
- -- Obj : Class_Wide_Type renames
- -- (... Ada.Tags.Displace (Temp));
+ -- Obj1 : CW_Type renames (... Ada.Tags.Displace (Src_Obj));
+ -- Tmp : ... := Function_Call (...)'reference;
+ -- Obj2 : CW_Type renames (... Ada.Tags.Displace (Tmp));
- elsif Is_Displacement_Of_Ctrl_Function_Result (Obj_Id) then
+ elsif Is_Displacement_Of_Object_Or_Function_Result (Obj_Id) then
return True;
end if;
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 535a4ff..9f3ae2a 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -521,11 +521,12 @@ package Exp_Util is
-- False otherwise. True for an empty list. It is an error to call this
-- routine with No_List as the argument.
- function Is_Displacement_Of_Ctrl_Function_Result
+ function Is_Displacement_Of_Object_Or_Function_Result
(Obj_Id : Entity_Id) return Boolean;
- -- Determine whether Obj_Id is a source object that has been initialized by
- -- a controlled function call later rewritten as a class-wide conversion of
- -- Ada.Tags.Displace.
+ -- Determine whether Obj_Id is a source entity that has been initialized by
+ -- either a controlled function call or the assignment of another source
+ -- object. In both cases the initialization expression is rewritten as a
+ -- class-wide conversion of Ada.Tags.Displace.
function Is_Finalizable_Transient
(Decl : Node_Id;
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 46a8b19..fc95bb8 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -5316,7 +5316,18 @@ package body Sem_Res is
-- needs extending because we can generate procedure calls that need
-- freezing.
- if Is_Entity_Name (Subp) and then not In_Spec_Expression then
+ -- In Ada 2012, expression functions may be called within pre/post
+ -- conditions of subsequent functions or expression functions. Such
+ -- calls do not freeze when they appear within generated bodies, which
+ -- would place the freeze node in the wrong scope. An expression
+ -- function is frozen in the usual fashion, by the appearance of a real
+ -- body, or at the end of a declarative part.
+
+ if Is_Entity_Name (Subp) and then not In_Spec_Expression
+ and then
+ (not Is_Expression_Function (Entity (Subp))
+ or else Scope (Entity (Subp)) = Current_Scope)
+ then
Freeze_Expression (Subp);
end if;