This change is aimed at eliminating some access checks that are superfluous because the access object that is subject to the check can never be null.
The 1st part makes it so that no access check is generated for the dereference of a temporary created to hold the 'Reference of some object: R2b : constant A1b := xxxxxxxxxxx'Reference; R2b.all Only 3 such cases have been identified, but Remove_Side_Effects is among them. The 2nd patch makes it so that no access check is generated for the pervasive Get_Current_Excep.all.all idiom used in exception handlers. This is already the case for the first dereference because the access-to-function type has access checks suppressed, but not for the second one. No functional changes. Tested on x86_64-pc-linux-gnu, committed on trunk 2011-11-20 Eric Botcazou <ebotca...@adacore.com> * exp_ch6.adb (Make_Build_In_Place_Call_In_Assignment): Declare NEW_EXPR local variable and attach the temporary to it. Set Is_Known_Non_Null on the temporary. (Make_Build_In_Place_Call_In_Object_Declaration): Likewise. * exp_util.adb (Remove_Side_Effects): Set Is_Known_Non_Null on the temporary created to hold the 'Reference of the expression, if any. * checks.adb (Install_Null_Excluding_Check): Bail out for the Get_Current_Excep.all.all idiom generated by the expander.
Index: exp_util.adb =================================================================== --- exp_util.adb (revision 181528) +++ exp_util.adb (working copy) @@ -6712,6 +6712,7 @@ New_Exp := E; else New_Exp := Make_Reference (Loc, E); + Set_Is_Known_Non_Null (Def_Id); end if; end if; Index: checks.adb =================================================================== --- checks.adb (revision 181528) +++ checks.adb (working copy) @@ -5673,6 +5673,22 @@ return; end if; + -- No check needed for the Get_Current_Excep.all.all idiom generated by + -- the expander within exception handlers, since we know that the value + -- can never be null. + + -- Is this really the right way to do this? Normally we generate such + -- code in the expander with checks off, and that's how we suppress this + -- kind of junk check ??? + + if Nkind (N) = N_Function_Call + and then Nkind (Name (N)) = N_Explicit_Dereference + and then Nkind (Prefix (Name (N))) = N_Identifier + and then Is_RTE (Entity (Prefix (Name (N))), RE_Get_Current_Excep) + then + return; + end if; + -- Otherwise install access check Insert_Action (N, Index: exp_ch6.adb =================================================================== --- exp_ch6.adb (revision 181528) +++ exp_ch6.adb (working copy) @@ -7954,6 +7954,7 @@ Obj_Id : Entity_Id; Ptr_Typ : Entity_Id; Ptr_Typ_Decl : Node_Id; + New_Expr : Node_Id; Result_Subt : Entity_Id; Target : Node_Id; @@ -8035,14 +8036,17 @@ -- Finally, create an access object initialized to a reference to the -- function call. - Obj_Id := Make_Temporary (Loc, 'R'); + New_Expr := Make_Reference (Loc, Relocate_Node (Func_Call)); + + Obj_Id := Make_Temporary (Loc, 'R', New_Expr); Set_Etype (Obj_Id, Ptr_Typ); + Set_Is_Known_Non_Null (Obj_Id); Obj_Decl := Make_Object_Declaration (Loc, Defining_Identifier => Obj_Id, Object_Definition => New_Reference_To (Ptr_Typ, Loc), - Expression => Make_Reference (Loc, Relocate_Node (Func_Call))); + Expression => New_Expr); Insert_After_And_Analyze (Ptr_Typ_Decl, Obj_Decl); Rewrite (Assign, Make_Null_Statement (Loc)); @@ -8301,6 +8305,7 @@ Def_Id := Make_Temporary (Loc, 'R', New_Expr); Set_Etype (Def_Id, Ref_Type); + Set_Is_Known_Non_Null (Def_Id); Insert_After_And_Analyze (Ptr_Typ_Decl, Make_Object_Declaration (Loc,