aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_util.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2011-12-20 15:00:46 +0100
committerArnaud Charlet <charlet@gcc.gnu.org>2011-12-20 15:00:46 +0100
commit2f7b74678b21c5c104c984cec26403bbefa27b76 (patch)
treefe6c67803b376fd6b34bafbde01819f5aa89d330 /gcc/ada/exp_util.adb
parentb26f70a095903c480d39d986a3e729f97f1fa88d (diff)
downloadgcc-2f7b74678b21c5c104c984cec26403bbefa27b76.zip
gcc-2f7b74678b21c5c104c984cec26403bbefa27b76.tar.gz
gcc-2f7b74678b21c5c104c984cec26403bbefa27b76.tar.bz2
[multiple changes]
2011-12-20 Hristian Kirtchev <kirtchev@adacore.com> * exp_ch11.adb (Find_Local_Handler): Guard the search over individual exception choices in case the list of handlers contains other (possibly illegal) constructs. 2011-12-20 Gary Dismukes <dismukes@adacore.com> * sem_ch8.adb (Find_Type): Test taggedness of the Available_Type when checking for an illegal use of an incomplete type, when the incomplete view is a limited view of a type. Remove redundant Is_Tagged test. 2011-12-20 Hristian Kirtchev <kirtchev@adacore.com> * exp_util.adb: Add with and use clause for Aspects. (Is_Finalizable_Transient): Objects which denote Ada containers in the context of iterators are not considered transients. Such object must live for as long as the loop is around. (Is_Iterated_Container): New routine. 2011-12-20 Hristian Kirtchev <kirtchev@adacore.com> * exp_imgv.adb (Expand_Width_Attribute): Add a type conversion from the enumeration subtype to its base subtype. From-SVN: r182539
Diffstat (limited to 'gcc/ada/exp_util.adb')
-rw-r--r--gcc/ada/exp_util.adb100
1 files changed, 99 insertions, 1 deletions
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 52541ed..dd5fc98 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Aspects; use Aspects;
with Atree; use Atree;
with Casing; use Casing;
with Checks; use Checks;
@@ -3966,6 +3967,13 @@ package body Exp_Util is
function Is_Allocated (Trans_Id : Entity_Id) return Boolean;
-- Determine whether transient object Trans_Id is allocated on the heap
+ function Is_Iterated_Container
+ (Trans_Id : Entity_Id;
+ First_Stmt : Node_Id) return Boolean;
+ -- Determine whether transient object Trans_Id denotes a container which
+ -- is in the process of being iterated in the statement list starting
+ -- from First_Stmt.
+
---------------------------
-- Initialized_By_Access --
---------------------------
@@ -4180,6 +4188,90 @@ package body Exp_Util is
and then Nkind (Expr) = N_Allocator;
end Is_Allocated;
+ ---------------------------
+ -- Is_Iterated_Container --
+ ---------------------------
+
+ function Is_Iterated_Container
+ (Trans_Id : Entity_Id;
+ First_Stmt : Node_Id) return Boolean
+ is
+ Aspect : Node_Id;
+ Call : Node_Id;
+ Iter : Entity_Id;
+ Param : Node_Id;
+ Stmt : Node_Id;
+ Typ : Entity_Id;
+
+ begin
+ -- It is not possible to iterate over containers in non-Ada 2012 code
+
+ if Ada_Version < Ada_2012 then
+ return False;
+ end if;
+
+ Typ := Etype (Trans_Id);
+
+ -- Handle access type created for secondary stack use
+
+ if Is_Access_Type (Typ) then
+ Typ := Designated_Type (Typ);
+ end if;
+
+ -- Look for aspect Default_Iterator
+
+ if Has_Aspects (Parent (Typ)) then
+ Aspect := Find_Aspect (Typ, Aspect_Default_Iterator);
+
+ if Present (Aspect) then
+ Iter := Entity (Aspect);
+
+ -- Examine the statements following the container object and
+ -- look for a call to the default iterate routine where the
+ -- first parameter is the transient. Such a call appears as:
+
+ -- It : Access_To_CW_Iterator :=
+ -- Iterate (Tran_Id.all, ...)'reference;
+
+ Stmt := First_Stmt;
+ while Present (Stmt) loop
+
+ -- Detect an object declaration which is initialized by a
+ -- secondary stack function call.
+
+ if Nkind (Stmt) = N_Object_Declaration
+ and then Present (Expression (Stmt))
+ and then Nkind (Expression (Stmt)) = N_Reference
+ and then Nkind (Prefix (Expression (Stmt))) =
+ N_Function_Call
+ then
+ Call := Prefix (Expression (Stmt));
+
+ -- The call must invoke the default iterate routine of
+ -- the container and the transient object must appear as
+ -- the first actual parameter.
+
+ if Entity (Name (Call)) = Iter
+ and then Present (Parameter_Associations (Call))
+ then
+ Param := First (Parameter_Associations (Call));
+
+ if Nkind (Param) = N_Explicit_Dereference
+ and then Entity (Prefix (Param)) = Trans_Id
+ then
+ return True;
+ end if;
+ end if;
+ end if;
+
+ Next (Stmt);
+ end loop;
+ end if;
+ end if;
+
+ return False;
+ end Is_Iterated_Container;
+
-- Start of processing for Is_Finalizable_Transient
begin
@@ -4220,7 +4312,13 @@ package body Exp_Util is
-- Do not consider conversions of tags to class-wide types
- and then not Is_Tag_To_CW_Conversion (Obj_Id);
+ and then not Is_Tag_To_CW_Conversion (Obj_Id)
+
+ -- Do not consider containers in the context of iterator loops. Such
+ -- transient objects must exist for as long as the loop is around,
+ -- otherwise any operation carried out by the iterator will fail.
+
+ and then not Is_Iterated_Container (Obj_Id, Decl);
end Is_Finalizable_Transient;
---------------------------------