summaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch4.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r--gcc/ada/exp_ch4.adb48
1 files changed, 30 insertions, 18 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 2b3c28b0994..0e7af41de90 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -7358,6 +7358,7 @@ package body Exp_Ch4 is
Disc : Entity_Id;
New_N : Node_Id;
Dcon : Elmt_Id;
+ Dval : Node_Id;
function In_Left_Hand_Side (Comp : Node_Id) return Boolean;
-- Gigi needs a temporary for prefixes that depend on a discriminant,
@@ -7472,18 +7473,6 @@ package body Exp_Ch4 is
then
null;
- -- If this is a discriminant of a component of a mutable record,
- -- or a renaming of such, no optimization is possible, and value
- -- must be retrieved anew. Note that in the previous case we may
- -- be dealing with a renaming declaration, while here we may have
- -- a use of a renaming.
-
- elsif Nkind (P) = N_Selected_Component
- and then Is_Record_Type (Etype (Prefix (P)))
- and then not Is_Constrained (Etype (Prefix (P)))
- then
- null;
-
-- Don't do this optimization if we are within the code for a
-- discriminant check, since the whole point of such a check may
-- be to verify the condition on which the code below depends!
@@ -7501,7 +7490,9 @@ package body Exp_Ch4 is
Disc := First_Discriminant (Ptyp);
Dcon := First_Elmt (Discriminant_Constraint (Ptyp));
+
Discr_Loop : while Present (Dcon) loop
+ Dval := Node (Dcon);
-- Check if this is the matching discriminant
@@ -7512,9 +7503,30 @@ package body Exp_Ch4 is
-- constrained by an outer discriminant, which cannot
-- be optimized away.
- if
- Denotes_Discriminant
- (Node (Dcon), Check_Concurrent => True)
+ if Denotes_Discriminant
+ (Dval, Check_Concurrent => True)
+ then
+ exit Discr_Loop;
+
+ elsif Nkind (Original_Node (Dval)) = N_Selected_Component
+ and then
+ Denotes_Discriminant
+ (Selector_Name (Original_Node (Dval)), True)
+ then
+ exit Discr_Loop;
+
+ -- Do not retrieve value if constraint is not static. It
+ -- is generally not useful, and the constraint may be a
+ -- rewritten outer discriminant in which case it is in
+ -- fact incorrect.
+
+ elsif Is_Entity_Name (Dval)
+ and then Nkind (Parent (Entity (Dval)))
+ = N_Object_Declaration
+ and then Present (Expression (Parent (Entity (Dval))))
+ and then
+ not Is_Static_Expression
+ (Expression (Parent (Entity (Dval))))
then
exit Discr_Loop;
@@ -7524,14 +7536,14 @@ package body Exp_Ch4 is
-- missing cases.
elsif Nkind (Parent (N)) = N_Case_Statement
- and then Etype (Node (Dcon)) /= Etype (Disc)
+ and then Etype (Dval) /= Etype (Disc)
then
Rewrite (N,
Make_Qualified_Expression (Loc,
Subtype_Mark =>
New_Occurrence_Of (Etype (Disc), Loc),
Expression =>
- New_Copy_Tree (Node (Dcon))));
+ New_Copy_Tree (Dval)));
Analyze_And_Resolve (N, Etype (Disc));
-- In case that comes out as a static expression,
@@ -7548,7 +7560,7 @@ package body Exp_Ch4 is
-- yet, and this must be done now.
else
- Rewrite (N, New_Copy_Tree (Node (Dcon)));
+ Rewrite (N, New_Copy_Tree (Dval));
Analyze_And_Resolve (N);
Set_Is_Static_Expression (N, False);
return;