aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/lib-xref.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/lib-xref.adb')
-rw-r--r--gcc/ada/lib-xref.adb154
1 files changed, 114 insertions, 40 deletions
diff --git a/gcc/ada/lib-xref.adb b/gcc/ada/lib-xref.adb
index c12f794..b0a96af 100644
--- a/gcc/ada/lib-xref.adb
+++ b/gcc/ada/lib-xref.adb
@@ -44,7 +44,7 @@ with Stand; use Stand;
with Table; use Table;
with Widechar; use Widechar;
-with GNAT.Heap_Sort_A;
+with GNAT.Heap_Sort_G;
package body Lib.Xref is
@@ -200,11 +200,11 @@ package body Lib.Xref is
------------------------
procedure Generate_Reference
- (E : Entity_Id;
- N : Node_Id;
- Typ : Character := 'r';
- Set_Ref : Boolean := True;
- Force : Boolean := False)
+ (E : Entity_Id;
+ N : Node_Id;
+ Typ : Character := 'r';
+ Set_Ref : Boolean := True;
+ Force : Boolean := False)
is
Indx : Nat;
Nod : Node_Id;
@@ -212,18 +212,25 @@ package body Lib.Xref is
Def : Source_Ptr;
Ent : Entity_Id;
+ Kind : Entity_Kind;
+ Call : Node_Id;
+ -- Arguments used in call to Find_Actual_Mode
+
function Is_On_LHS (Node : Node_Id) return Boolean;
-- Used to check if a node is on the left hand side of an assignment.
-- The following cases are handled:
--
- -- Variable Node is a direct descendant of an assignment statement.
+ -- Variable Node is a direct descendant of left hand side of an
+ -- assignment statement.
+ --
+ -- Prefix Of an indexed or selected component that is present in
+ -- a subtree rooted by an assignment statement. There is
+ -- no restriction of nesting of components, thus cases
+ -- such as A.B (C).D are handled properly. However a prefix
+ -- of a dereference (either implicit or explicit) is never
+ -- considered as on a LHS.
--
- -- Prefix Of an indexed or selected component that is present in a
- -- subtree rooted by an assignment statement. There is no
- -- restriction of nesting of components, thus cases such as
- -- A.B (C).D are handled properly.
- -- However a prefix of a dereference (either implicit or
- -- explicit) is never considered as on a LHS.
+ -- Out param Same as above cases, but OUT parameter
---------------
-- Is_On_LHS --
@@ -235,28 +242,41 @@ package body Lib.Xref is
-- Sem_Util.May_Be_Lvalue
-- Sem_Util.Known_To_Be_Assigned
-- Exp_Ch2.Expand_Entry_Parameter.In_Assignment_Context
+ -- Exp_Smem.Is_Out_Actual
function Is_On_LHS (Node : Node_Id) return Boolean is
- N : Node_Id := Node;
+ N : Node_Id;
+ P : Node_Id;
+ K : Node_Kind;
begin
-- Only identifiers are considered, is this necessary???
- if Nkind (N) /= N_Identifier then
+ if Nkind (Node) /= N_Identifier then
return False;
end if;
- -- Reach the assignment statement subtree root. In the case of a
- -- variable being a direct descendant of an assignment statement,
- -- the loop is skiped.
+ -- Immediat return if appeared as OUT parameter
- while Nkind (Parent (N)) /= N_Assignment_Statement loop
+ if Kind = E_Out_Parameter then
+ return True;
+ end if;
- -- Check whether the parent is a component and the current node
- -- is its prefix, but return False if the current node has an
- -- access type, as in that case the selected or indexed component
- -- is an implicit dereference, and the LHS is the designated
- -- object, not the access object.
+ -- Search for assignment statement subtree root
+
+ N := Node;
+ loop
+ P := Parent (N);
+ K := Nkind (P);
+
+ if K = N_Assignment_Statement then
+ return Name (P) = N;
+
+ -- Check whether the parent is a component and the current node is
+ -- its prefix, but return False if the current node has an access
+ -- type, as in that case the selected or indexed component is an
+ -- implicit dereference, and the LHS is the designated object, not
+ -- the access object.
-- ??? case of a slice assignment?
@@ -267,15 +287,16 @@ package body Lib.Xref is
-- dereference. If the dereference is on an LHS, this causes a
-- false positive.
- if (Nkind (Parent (N)) = N_Selected_Component
- or else
- Nkind (Parent (N)) = N_Indexed_Component)
- and then Prefix (Parent (N)) = N
+ elsif (K = N_Selected_Component or else K = N_Indexed_Component)
+ and then Prefix (P) = N
and then not (Present (Etype (N))
and then
Is_Access_Type (Etype (N)))
then
- N := Parent (N);
+ N := P;
+
+ -- All other cases, definitely not on left side
+
else
return False;
end if;
@@ -290,6 +311,7 @@ package body Lib.Xref is
begin
pragma Assert (Nkind (E) in N_Entity);
+ Find_Actual_Mode (N, Kind, Call);
-- Check for obsolescent reference to package ASCII. GNAT treats this
-- element of annex J specially since in practice, programs make a lot
@@ -393,7 +415,18 @@ package body Lib.Xref is
if (Ekind (E) = E_Variable or else Is_Formal (E))
and then Is_On_LHS (N)
then
- Set_Referenced_As_LHS (E);
+ -- If we have the OUT parameter case and the warning mode for
+ -- OUT parameters is not set, treat this as an ordinary reference
+ -- since we don't want warnings about it being unset.
+
+ if Kind = E_Out_Parameter and not Warn_On_Out_Parameter_Unread then
+ Set_Referenced (E);
+
+ -- For other cases, set referenced on LHS
+
+ else
+ Set_Referenced_As_LHS (E);
+ end if;
-- Check for a reference in a pragma that should not count as a
-- making the variable referenced for warning purposes.
@@ -433,13 +466,49 @@ package body Lib.Xref is
then
null;
- -- Any other occurrence counts as referencing the entity
+ -- All other cases
else
- Set_Referenced (E);
+ -- Special processing for IN OUT and OUT parameters, where we
+ -- have an implicit assignment to a simple variable.
+
+ if (Kind = E_Out_Parameter or else Kind = E_In_Out_Parameter)
+ and then Is_Entity_Name (N)
+ and then Present (Entity (N))
+ and then Is_Assignable (Entity (N))
+ then
+ -- Record implicit assignment unless we have an intrinsic
+ -- subprogram, which is most likely an instantiation of
+ -- Unchecked_Deallocation which we do not want to consider
+ -- as an assignment since it generates false positives. We
+ -- also exclude the case of an IN OUT parameter to a procedure
+ -- called Free, since we suspect similar semantics.
+
+ if Is_Entity_Name (Name (Call))
+ and then not Is_Intrinsic_Subprogram (Entity (Name (Call)))
+ and then (Kind /= E_In_Out_Parameter
+ or else Chars (Name (Call)) /= Name_Free)
+ then
+ Set_Referenced_As_LHS (E);
+ end if;
+
+ -- For IN OUT case, treat as also being normal reference
+
+ if Kind = E_In_Out_Parameter then
+ Set_Referenced (E);
+ end if;
+
+ -- Any other occurrence counts as referencing the entity
+
+ else
+ Set_Referenced (E);
+
+ -- If variable, this is an OK reference after an assignment
+ -- so we can clear the Last_Assignment indication.
- if Ekind (E) = E_Variable then
- Set_Last_Assignment (E, Empty);
+ if Is_Assignable (E) then
+ Set_Last_Assignment (E, Empty);
+ end if;
end if;
end if;
@@ -954,11 +1023,14 @@ package body Lib.Xref is
Handle_Orphan_Type_References : declare
J : Nat;
Tref : Entity_Id;
- L, R : Character;
Indx : Nat;
Ent : Entity_Id;
Loc : Source_Ptr;
+ L, R : Character;
+ pragma Warnings (Off, L);
+ pragma Warnings (Off, R);
+
procedure New_Entry (E : Entity_Id);
-- Make an additional entry into the Xref table for a type entity
-- that is related to the current entity (parent, type ancestor,
@@ -1140,6 +1212,8 @@ package body Lib.Xref is
procedure Move (From : Natural; To : Natural);
-- Move procedure for Sort call
+ package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
+
--------
-- Lt --
--------
@@ -1230,10 +1304,7 @@ package body Lib.Xref is
-- Sort the references
- GNAT.Heap_Sort_A.Sort
- (Integer (Nrefs),
- Move'Unrestricted_Access,
- Lt'Unrestricted_Access);
+ Sorting.Sort (Integer (Nrefs));
-- Eliminate duplicate entries
@@ -1272,9 +1343,12 @@ package body Lib.Xref is
for Refno in 1 .. Nrefs loop
Output_One_Ref : declare
P2 : Source_Ptr;
+ Ent : Entity_Id;
+
WC : Char_Code;
Err : Boolean;
- Ent : Entity_Id;
+ pragma Warnings (Off, WC);
+ pragma Warnings (Off, Err);
XE : Xref_Entry renames Xrefs.Table (Rnums (Refno));
-- The current entry to be accessed