diff options
author | Justin Squirek <squirek@adacore.com> | 2020-03-12 07:01:43 -0400 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2020-06-15 04:04:31 -0400 |
commit | 773e99ac3e61bd84f9848e78e17867a920f9ae53 (patch) | |
tree | 2be9737f01ffa0ed2c05f6d40ffddbad55c9802c /gcc/ada/exp_ch4.adb | |
parent | fdcbc0764dee19e9e1eeeb17c960567474b4d688 (diff) | |
download | gcc-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.adb | 86 |
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; |