summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch4.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2008-05-26 13:12:35 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2008-05-26 13:12:35 +0000
commit68bac88c06ecfdfc2e2e53e6d333cf21b40c946b (patch)
tree738ec625d7b4f862f8a375567d6c4552506297ab /gcc/ada/exp_ch4.adb
parente7721248eaa90ce0223f4cd036962628d388bdef (diff)
downloadgcc-68bac88c06ecfdfc2e2e53e6d333cf21b40c946b.tar.gz
2008-05-26 Ed Schonberg <schonberg@adacore.com>
* exp_ch4.adb (Expand_Concatenate_Other): Add explicit constraint checks on the upper bound if the index type is a modular type, to prevent wrap-around computations when size is close to upper bound of type. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@135918 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r--gcc/ada/exp_ch4.adb62
1 files changed, 58 insertions, 4 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 1eb727392d9..f009f00923b 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -2230,6 +2230,7 @@ package body Exp_Ch4 is
Declare_Stmts : List_Id;
H_Decl : Node_Id;
+ I_Decl : Node_Id;
H_Init : Node_Id;
P_Decl : Node_Id;
R_Decl : Node_Id;
@@ -2427,6 +2428,7 @@ package body Exp_Ch4 is
or else Root_Type (Ind_Typ) = Standard_Integer
or else Root_Type (Ind_Typ) = Standard_Short_Integer
or else Root_Type (Ind_Typ) = Standard_Short_Short_Integer
+ or else Is_Modular_Integer_Type (Ind_Typ)
then
Target_Type := Standard_Integer;
else
@@ -2609,7 +2611,37 @@ package body Exp_Ch4 is
for I in 2 .. Nb_Opnds loop
H_Init := Make_Op_Add (Loc, H_Init, S_Length (I));
end loop;
- H_Init := Ind_Val (Make_Op_Add (Loc, H_Init, L_Pos));
+
+ -- If the index type is small modular type, we need to perform an
+ -- additional check that the upper bound fits in the index type.
+ -- Otherwise the computation of the upper bound can wrap around
+ -- and yield meaningless results. The constraint check has to be
+ -- explicit in the code, because the generated function is compiled
+ -- with checks disabled, for efficiency.
+
+ if Is_Modular_Integer_Type (Ind_Typ)
+ and then Esize (Ind_Typ) < Esize (Standard_Integer)
+ then
+ I_Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Make_Defining_Identifier (Loc, Name_uI),
+ Object_Definition => New_Reference_To (Standard_Integer, Loc),
+ Expression =>
+ Make_Type_Conversion (Loc,
+ New_Reference_To (Standard_Integer, Loc),
+ Make_Op_Add (Loc, H_Init, L_Pos)));
+
+ H_Init :=
+ Ind_Val (
+ Make_Type_Conversion (Loc,
+ New_Reference_To (Ind_Typ, Loc),
+ New_Reference_To (Defining_Identifier (I_Decl), Loc)));
+
+ -- For other index types, computation is safe.
+
+ else
+ H_Init := Ind_Val (Make_Op_Add (Loc, H_Init, L_Pos));
+ end if;
H_Decl :=
Make_Object_Declaration (Loc,
@@ -2636,6 +2668,28 @@ package body Exp_Ch4 is
Declare_Decls := New_List (P_Decl, H_Decl, R_Decl);
+ -- Add constraint check for the modular index case.
+
+ if Is_Modular_Integer_Type (Ind_Typ)
+ and then Esize (Ind_Typ) < Esize (Standard_Integer)
+ then
+ Insert_After (P_Decl, I_Decl);
+
+ Insert_After (I_Decl,
+ Make_Raise_Constraint_Error (Loc,
+ Condition =>
+ Make_Op_Gt (Loc,
+ Left_Opnd =>
+ New_Reference_To (Defining_Identifier (I_Decl), Loc),
+ Right_Opnd =>
+ Make_Type_Conversion (Loc,
+ New_Reference_To (Standard_Integer, Loc),
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Ind_Typ, Loc),
+ Attribute_Name => Name_Last))),
+ Reason => CE_Range_Check_Failed));
+ end if;
+
-- Construct list of statements for the declare block
Declare_Stmts := New_List;
@@ -7679,13 +7733,13 @@ package body Exp_Ch4 is
if Nkind (Parent (N)) = Sinfo.N_Return_Statement then
declare
- Func : Entity_Id := Current_Scope;
+ Func : Entity_Id;
Func_Typ : Entity_Id;
begin
- -- Climb the scope stack looking for the enclosing
- -- function.
+ -- Climb scope stack looking for the enclosing function
+ Func := Current_Scope;
while Present (Func)
and then Ekind (Func) /= E_Function
loop