Commit 3d6db7f8 by Gary Dismukes Committed by Arnaud Charlet

exp_attr.adb (Expand_N_Attribute_Reference): Apply a predicate check when…

exp_attr.adb (Expand_N_Attribute_Reference): Apply a predicate check when evaluating the attribute Valid...

2012-11-06  Gary Dismukes  <dismukes@adacore.com>

	* exp_attr.adb (Expand_N_Attribute_Reference): Apply a predicate
	check when evaluating the attribute Valid, and issue a warning
	about infinite recursion when the check occurs within the
	predicate function of the prefix's subtype.
	* exp_ch4.adb (Expand_N_In): Remove test for Is_Discrete_Type
	when we're checking that there's no predicate check function as a
	condition for substituting a Valid check for a scalar membership
	test (substitution should be suppressed for any kind of scalar
	subtype with a predicate check). Also, don't emit a predicate
	check when the right operand is a range.

From-SVN: r193228
parent 150ac76e
2012-11-06 Gary Dismukes <dismukes@adacore.com>
* exp_attr.adb (Expand_N_Attribute_Reference): Apply a predicate
check when evaluating the attribute Valid, and issue a warning
about infinite recursion when the check occurs within the
predicate function of the prefix's subtype.
* exp_ch4.adb (Expand_N_In): Remove test for Is_Discrete_Type
when we're checking that there's no predicate check function as a
condition for substituting a Valid check for a scalar membership
test (substitution should be suppressed for any kind of scalar
subtype with a predicate check). Also, don't emit a predicate
check when the right operand is a range.
2012-11-06 Robert Dewar <dewar@adacore.com>
* par_sco.adb, bindgen.adb, exp_vfpt.adb, exp_vfpt.ads, exp_ch2.adb,
......
......@@ -27,6 +27,7 @@ with Atree; use Atree;
with Checks; use Checks;
with Einfo; use Einfo;
with Elists; use Elists;
with Errout; use Errout;
with Exp_Atag; use Exp_Atag;
with Exp_Ch2; use Exp_Ch2;
with Exp_Ch3; use Exp_Ch3;
......@@ -5608,6 +5609,32 @@ package body Exp_Attr is
Rewrite (N, Make_Range_Test);
end if;
-- If a predicate is present, then we do the predicate test, even if
-- within the predicate function (infinite recursion is warned about
-- in that case).
declare
Pred_Func : constant Entity_Id := Predicate_Function (Ptyp);
begin
if Present (Pred_Func) then
Rewrite (N,
Make_And_Then (Loc,
Left_Opnd => Relocate_Node (N),
Right_Opnd => Make_Predicate_Call (Ptyp, Pref)));
-- If the attribute appears within the subtype's own predicate
-- function, then issue a warning that this will cause infinite
-- recursion.
if Current_Scope = Pred_Func then
Error_Msg_N
("attribute Valid requires a predicate check?", N);
Error_Msg_N ("\and will result in infinite recursion?", N);
end if;
end if;
end;
Analyze_And_Resolve (N, Standard_Boolean);
Validity_Checks_On := Save_Validity_Checks_On;
end Valid;
......
......@@ -5565,8 +5565,7 @@ package body Exp_Ch4 is
-- Skip this for predicated types, where such expressions are a
-- reasonable way of testing if something meets the predicate.
and then not (Is_Discrete_Type (Ltyp)
and then Present (Predicate_Function (Ltyp)))
and then not Present (Predicate_Function (Ltyp))
then
Substitute_Valid_Check;
return;
......@@ -6103,6 +6102,9 @@ package body Exp_Ch4 is
-- If a predicate is present, then we do the predicate test, but we
-- most certainly want to omit this if we are within the predicate
-- function itself, since otherwise we have an infinite recursion!
-- The check should also not be emitted when testing against a range
-- (the check is only done when the right operand is a subtype; see
-- RM12-4.5.2 (28.1/3-30/3)).
declare
PFunc : constant Entity_Id := Predicate_Function (Rtyp);
......@@ -6110,6 +6112,7 @@ package body Exp_Ch4 is
begin
if Present (PFunc)
and then Current_Scope /= PFunc
and then Nkind (Rop) /= N_Range
then
Rewrite (N,
Make_And_Then (Loc,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment