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 <[email protected]>
* 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,