diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2011-12-20 15:00:46 +0100 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2011-12-20 15:00:46 +0100 |
commit | 2f7b74678b21c5c104c984cec26403bbefa27b76 (patch) | |
tree | fe6c67803b376fd6b34bafbde01819f5aa89d330 /gcc/ada/exp_util.adb | |
parent | b26f70a095903c480d39d986a3e729f97f1fa88d (diff) | |
download | gcc-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.adb | 100 |
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; --------------------------------- |