summaryrefslogtreecommitdiff
path: root/gcc/ada/checks.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-31 10:20:38 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-08-31 10:20:38 +0000
commit7870823d1c823d0958171f7e14c29ed015dee61e (patch)
tree16ef625e05835919908dbc3e3d3f1c29170fccbd /gcc/ada/checks.adb
parent7670be607e56af50ff042355f76bdeda0236c7e8 (diff)
downloadgcc-7870823d1c823d0958171f7e14c29ed015dee61e.tar.gz
2007-08-31 Hristian Kirtchev <kirtchev@adacore.com>
* checks.adb (In_Declarative_Region_Of_Subprogram_Body): New routine. (Mark_Non_Null): If the node for which we just generated an access check is a reference to an *in* parameter and the reference appears in the declarative part of a subprogram body, mark the node as known non null. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127969 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/checks.adb')
-rw-r--r--gcc/ada/checks.adb98
1 files changed, 95 insertions, 3 deletions
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 027f5cbc73c..b025ce803e0 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -4988,8 +4988,83 @@ package body Checks is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
+ function In_Declarative_Region_Of_Subprogram_Body return Boolean;
+ -- Determine whether node N, a reference to an *in* parameter, is
+ -- inside the declarative region of the current subprogram body.
+
procedure Mark_Non_Null;
- -- After installation of check, marks node as non-null if entity
+ -- After installation of check, if the node in question is an entity
+ -- name, then mark this entity as non-null if possible.
+
+ ----------------------------------------------
+ -- In_Declarative_Region_Of_Subprogram_Body --
+ ----------------------------------------------
+
+ function In_Declarative_Region_Of_Subprogram_Body return Boolean is
+ E : constant Entity_Id := Entity (N);
+ S : constant Entity_Id := Current_Scope;
+ S_Par : Node_Id;
+
+ begin
+ pragma Assert (Ekind (E) = E_In_Parameter);
+
+ -- Two initial context checks. We must be inside a subprogram body
+ -- with declarations and reference must not appear in nested scopes.
+
+ if (Ekind (S) /= E_Function
+ and then Ekind (S) /= E_Procedure)
+ or else Scope (E) /= S
+ then
+ return False;
+ end if;
+
+ S_Par := Parent (Parent (S));
+
+ if Nkind (S_Par) /= N_Subprogram_Body
+ or else No (Declarations (S_Par))
+ then
+ return False;
+ end if;
+
+ declare
+ N_Decl : Node_Id;
+ P : Node_Id;
+
+ begin
+ -- Retrieve the declaration node of N (if any). Note that N
+ -- may be a part of a complex initialization expression.
+
+ P := Parent (N);
+ N_Decl := Empty;
+ while Present (P) loop
+
+ -- While traversing the parent chain, we find that N
+ -- belongs to a statement, thus it may never appear in
+ -- a declarative region.
+
+ if Nkind (P) in N_Statement_Other_Than_Procedure_Call
+ or else Nkind (P) = N_Procedure_Call_Statement
+ then
+ return False;
+ end if;
+
+ if Nkind (P) in N_Declaration
+ and then Nkind (P) not in N_Subprogram_Specification
+ then
+ N_Decl := P;
+ exit;
+ end if;
+
+ P := Parent (P);
+ end loop;
+
+ if No (N_Decl) then
+ return False;
+ end if;
+
+ return List_Containing (N_Decl) = Declarations (S_Par);
+ end;
+ end In_Declarative_Region_Of_Subprogram_Body;
-------------------
-- Mark_Non_Null --
@@ -4997,11 +5072,28 @@ package body Checks is
procedure Mark_Non_Null is
begin
+ -- Only case of interest is if node N is an entity name
+
if Is_Entity_Name (N) then
+
+ -- For sure, we want to clear an indication that this is known to
+ -- be null, since if we get past this check, it definitely is not!
+
Set_Is_Known_Null (Entity (N), False);
- if Safe_To_Capture_Value (N, Entity (N)) then
- Set_Is_Known_Non_Null (Entity (N), True);
+ -- We can mark the entity as known to be non-null if either it is
+ -- safe to capture the value, or in the case of an IN parameter,
+ -- which is a constant, if the check we just installed is in the
+ -- declarative region of the subprogram body. In this latter case,
+ -- a check is decisive for the rest of the body, since we know we
+ -- must complete all declarations before executing the body.
+
+ if Safe_To_Capture_Value (N, Entity (N))
+ or else
+ (Ekind (Entity (N)) = E_In_Parameter
+ and then In_Declarative_Region_Of_Subprogram_Body)
+ then
+ Set_Is_Known_Non_Null (Entity (N));
end if;
end if;
end Mark_Non_Null;