===================================================================
@@ -4440,7 +4440,8 @@
----------
-- 1. Deal with enumeration types with holes
- -- 2. For floating-point, generate call to attribute function
+ -- 2. For floating-point, generate call to attribute function and deal
+ -- with range checking if Check_Float_Overflow modde.
-- 3. For other cases, deal with constraint checking
when Attribute_Pred => Pred :
@@ -4512,9 +4513,36 @@
Analyze_And_Resolve (N, Typ);
-- For floating-point, we transform 'Pred into a call to the Pred
- -- floating-point attribute function in Fat_xxx (xxx is root type)
+ -- floating-point attribute function in Fat_xxx (xxx is root type).
elsif Is_Floating_Point_Type (Ptyp) then
+
+ -- Handle case of range check. The Do_Range_Check flag is set only
+ -- in Check_Float_Overflow mode, and what we need is a specific
+ -- check against typ'First, since that is the only overflow case.
+
+ declare
+ Expr : constant Node_Id := First (Exprs);
+ begin
+ if Do_Range_Check (Expr) then
+ Set_Do_Range_Check (Expr, False);
+ Insert_Action (N,
+ Make_Raise_Constraint_Error (Loc,
+ Condition =>
+ Make_Op_Eq (Loc,
+ Left_Opnd => Duplicate_Subexpr (Expr),
+ Right_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_First,
+ Prefix =>
+ New_Occurrence_Of (Base_Type (Ptyp), Loc))),
+ Reason => CE_Range_Check_Failed),
+ Suppress => All_Checks);
+ end if;
+ end;
+
+ -- Transform into call to attribute function
+
Expand_Fpt_Attribute_R (N);
Analyze_And_Resolve (N, Typ);
@@ -5563,6 +5591,33 @@
-- floating-point attribute function in Fat_xxx (xxx is root type)
elsif Is_Floating_Point_Type (Ptyp) then
+
+ -- Handle case of range check. The Do_Range_Check flag is set only
+ -- in Check_Float_Overflow mode, and what we need is a specific
+ -- check against typ'Last, since that is the only overflow case.
+
+ declare
+ Expr : constant Node_Id := First (Exprs);
+ begin
+ if Do_Range_Check (Expr) then
+ Set_Do_Range_Check (Expr, False);
+ Insert_Action (N,
+ Make_Raise_Constraint_Error (Loc,
+ Condition =>
+ Make_Op_Eq (Loc,
+ Left_Opnd => Duplicate_Subexpr (Expr),
+ Right_Opnd =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Last,
+ Prefix =>
+ New_Occurrence_Of (Base_Type (Ptyp), Loc))),
+ Reason => CE_Range_Check_Failed),
+ Suppress => All_Checks);
+ end if;
+ end;
+
+ -- Transform into call to attribute function
+
Expand_Fpt_Attribute_R (N);
Analyze_And_Resolve (N, Typ);
===================================================================
@@ -2409,6 +2409,8 @@
end if;
end if;
+ -- Cases where prefix must be resolvable by itself
+
if Is_Overloaded (P)
and then Aname /= Name_Access
and then Aname /= Name_Address
@@ -4835,17 +4837,20 @@
if Is_Real_Type (P_Type) or else Is_Boolean_Type (P_Type) then
Error_Msg_Name_1 := Aname;
Error_Msg_Name_2 := Chars (P_Type);
- Check_SPARK_Restriction
- ("attribute% is not allowed for type%", P);
+ Check_SPARK_Restriction ("attribute% is not allowed for type%", P);
end if;
Resolve (E1, P_Base_Type);
Set_Etype (N, P_Base_Type);
- -- Nothing to do for real type case
+ -- For real types, enable range check in Check_Overflow_Mode only
if Is_Real_Type (P_Type) then
- null;
+ if Check_Float_Overflow
+ and then not Range_Checks_Suppressed (P_Base_Type)
+ then
+ Enable_Range_Check (E1);
+ end if;
-- If not modular type, test for overflow check required
@@ -5739,17 +5744,20 @@
if Is_Real_Type (P_Type) or else Is_Boolean_Type (P_Type) then
Error_Msg_Name_1 := Aname;
Error_Msg_Name_2 := Chars (P_Type);
- Check_SPARK_Restriction
- ("attribute% is not allowed for type%", P);
+ Check_SPARK_Restriction ("attribute% is not allowed for type%", P);
end if;
Resolve (E1, P_Base_Type);
Set_Etype (N, P_Base_Type);
- -- Nothing to do for real type case
+ -- For real types, enable range check in Check_Overflow_Mode only
if Is_Real_Type (P_Type) then
- null;
+ if Check_Float_Overflow
+ and then not Range_Checks_Suppressed (P_Base_Type)
+ then
+ Enable_Range_Check (E1);
+ end if;
-- If not modular type, test for overflow check required