aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch4.adb
diff options
context:
space:
mode:
authorJustin Squirek <squirek@adacore.com>2020-03-12 07:01:43 -0400
committerPierre-Marie de Rodat <derodat@adacore.com>2020-06-15 04:04:31 -0400
commit773e99ac3e61bd84f9848e78e17867a920f9ae53 (patch)
tree2be9737f01ffa0ed2c05f6d40ffddbad55c9802c /gcc/ada/exp_ch4.adb
parentfdcbc0764dee19e9e1eeeb17c960567474b4d688 (diff)
downloadgcc-773e99ac3e61bd84f9848e78e17867a920f9ae53.zip
gcc-773e99ac3e61bd84f9848e78e17867a920f9ae53.tar.gz
gcc-773e99ac3e61bd84f9848e78e17867a920f9ae53.tar.bz2
[Ada] Bad access checks on if/case expression as actual
2020-06-15 Justin Squirek <squirek@adacore.com> gcc/ada/ * exp_ch4.adb (Expand_N_Case_Expression): Set default value for Target to silence potential warnings. (Expand_N_If_Expression): Add calculation to check when the if expression is used directly in the context of an actual of an anonymous access type and add a special path to force expansion of the if expression in this case. * exp_ch6.adb (Expand_Branch): Generate an assignment to the level temporary for a given branch. (Expand_Call_Helper): Add expansion to allow for creating a temporary to store associated accessiblity levels on each branch of the conditional expression. Also perform expansion of function calls into expressions with actions, and fixup references to N with Call_Node. (Insert_Level_Assign): Move through nested conditional expressions to each branch. * sem_util.ads, sem_util.adb (Is_Anonymous_Access_Actual): Added to detect when to force expansion of if expressions.
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r--gcc/ada/exp_ch4.adb86
1 files changed, 78 insertions, 8 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 7a84215..bf88225 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -5314,7 +5314,7 @@ package body Exp_Ch4 is
Case_Stmt : Node_Id;
Decl : Node_Id;
Expr : Node_Id;
- Target : Entity_Id;
+ Target : Entity_Id := Empty;
Target_Typ : Entity_Id;
In_Predicate : Boolean := False;
@@ -5771,11 +5771,21 @@ package body Exp_Ch4 is
Elsex : constant Node_Id := Next (Thenx);
Typ : constant Entity_Id := Etype (N);
- Actions : List_Id;
- Decl : Node_Id;
- Expr : Node_Id;
- New_If : Node_Id;
- New_N : Node_Id;
+ Actions : List_Id;
+ Decl : Node_Id;
+ Expr : Node_Id;
+ New_If : Node_Id;
+ New_N : Node_Id;
+
+ -- Determine if we are dealing with a special case of a conditional
+ -- expression used as an actual for an anonymous access type which
+ -- forces us to transform the if expression into an expression with
+ -- actions in order to create a temporary to capture the level of the
+ -- expression in each branch.
+
+ Force_Expand : constant Boolean := Is_Anonymous_Access_Actual (N);
+
+ -- Start of processing for Expand_N_If_Expression
begin
-- Check for MINIMIZED/ELIMINATED overflow mode
@@ -5975,9 +5985,13 @@ package body Exp_Ch4 is
end;
-- For other types, we only need to expand if there are other actions
- -- associated with either branch.
+ -- associated with either branch or we need to force expansion to deal
+ -- with if expressions used as an actual of an anonymous access type.
- elsif Present (Then_Actions (N)) or else Present (Else_Actions (N)) then
+ elsif Present (Then_Actions (N))
+ or else Present (Else_Actions (N))
+ or else Force_Expand
+ then
-- We now wrap the actions into the appropriate expression
@@ -6051,6 +6065,62 @@ package body Exp_Ch4 is
Analyze_And_Resolve (Elsex, Typ);
end if;
+ -- We must force expansion into an expression with actions when
+ -- an if expression gets used directly as an actual for an
+ -- anonymous access type.
+
+ if Force_Expand then
+ declare
+ Cnn : constant Entity_Id := Make_Temporary (Loc, 'C');
+ Acts : List_Id;
+ begin
+ Acts := New_List;
+
+ -- Generate:
+ -- Cnn : Ann;
+
+ Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Cnn,
+ Object_Definition => New_Occurrence_Of (Typ, Loc));
+ Append_To (Acts, Decl);
+
+ Set_No_Initialization (Decl);
+
+ -- Generate:
+ -- if Cond then
+ -- Cnn := <Thenx>;
+ -- else
+ -- Cnn := <Elsex>;
+ -- end if;
+
+ New_If :=
+ Make_Implicit_If_Statement (N,
+ Condition => Relocate_Node (Cond),
+ Then_Statements => New_List (
+ Make_Assignment_Statement (Sloc (Thenx),
+ Name => New_Occurrence_Of (Cnn, Sloc (Thenx)),
+ Expression => Relocate_Node (Thenx))),
+
+ Else_Statements => New_List (
+ Make_Assignment_Statement (Sloc (Elsex),
+ Name => New_Occurrence_Of (Cnn, Sloc (Elsex)),
+ Expression => Relocate_Node (Elsex))));
+ Append_To (Acts, New_If);
+
+ -- Generate:
+ -- do
+ -- ...
+ -- in Cnn end;
+
+ Rewrite (N,
+ Make_Expression_With_Actions (Loc,
+ Expression => New_Occurrence_Of (Cnn, Loc),
+ Actions => Acts));
+ Analyze_And_Resolve (N, Typ);
+ end;
+ end if;
+
return;
end if;