sem_ch5.adb (One_Bound): Fix latent bug involving secondary stack

2008-08-22  Robert Dewar  <dewar@adacore.com>

	* sem_ch5.adb (One_Bound): Fix latent bug involving secondary stack

From-SVN: r139464
This commit is contained in:
Robert Dewar 2008-08-22 15:26:19 +02:00 committed by Arnaud Charlet
parent 4c7ad32065
commit c9626ed6db
1 changed files with 42 additions and 7 deletions

View File

@ -1465,10 +1465,7 @@ package body Sem_Ch5 is
function One_Bound
(Original_Bound : Node_Id;
Analyzed_Bound : Node_Id) return Node_Id;
-- Create one declaration followed by one assignment statement
-- to capture the value of bound. We create a separate assignment
-- in order to force the creation of a block in case the bound
-- contains a call that uses the secondary stack.
-- Capture value of bound and return captured value
---------------
-- One_Bound --
@ -1499,15 +1496,53 @@ package body Sem_Ch5 is
then
Analyze_And_Resolve (Original_Bound, Typ);
return Original_Bound;
else
Analyze_And_Resolve (Original_Bound, Typ);
end if;
-- Here we need to capture the value
Analyze_And_Resolve (Original_Bound, Typ);
Id :=
Make_Defining_Identifier (Loc,
Chars => New_Internal_Name ('S'));
-- Normally, the best approach is simply to generate a constant
-- declaration that captures the bound. However, there is a nasty
-- case where this is wrong. If the bound is complex, and has a
-- possible use of the secondary stack, we need to generate a
-- separate assignment statement to ensure the creation of a block
-- which will release the secondary stack.
-- We prefer the constant declaration, since it leaves us with a
-- proper trace of the value, useful in optimizations that get rid
-- of junk range checks.
-- Probably we want something like the Side_Effect_Free routine
-- in Exp_Util, but for now, we just optimize the cases of 'Last
-- and 'First applied to an entity, since these are the important
-- cases for range check optimizations.
if Nkind (Original_Bound) = N_Attribute_Reference
and then (Attribute_Name (Original_Bound) = Name_First
or else
Attribute_Name (Original_Bound) = Name_Last)
and then Is_Entity_Name (Prefix (Original_Bound))
then
Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => Id,
Constant_Present => True,
Object_Definition => New_Occurrence_Of (Typ, Loc),
Expression => Relocate_Node (Original_Bound));
Insert_Before (Parent (N), Decl);
Analyze (Decl);
Rewrite (Original_Bound, New_Occurrence_Of (Id, Loc));
return Expression (Decl);
end if;
-- Here we make a declaration with a separate assignment statement
Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => Id,