summaryrefslogtreecommitdiff
path: root/gcc/ada/sem_util.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/sem_util.adb')
-rw-r--r--gcc/ada/sem_util.adb188
1 files changed, 145 insertions, 43 deletions
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 648362c658f..907efe4c1e6 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -2814,87 +2814,188 @@ package body Sem_Util is
Obj1 : Node_Id := A1;
Obj2 : Node_Id := A2;
- procedure Check_Renaming (Obj : in out Node_Id);
- -- If an object is a renaming, examine renamed object. If it is a
- -- dereference of a variable, or an indexed expression with non-constant
- -- indexes, no overlap check can be reported.
+ function Has_Prefix (N : Node_Id) return Boolean;
+ -- Return True if N has attribute Prefix
- --------------------
- -- Check_Renaming --
- --------------------
+ function Is_Renaming (N : Node_Id) return Boolean;
+ -- Return true if N names a renaming entity
+
+ function Is_Valid_Renaming (N : Node_Id) return Boolean;
+ -- For renamings, return False if the prefix of any dereference within
+ -- the renamed object_name is a variable, or any expression within the
+ -- renamed object_name contains references to variables or calls on
+ -- nonstatic functions; otherwise return True (RM 6.4.1(6.10/3))
- procedure Check_Renaming (Obj : in out Node_Id) is
+ ----------------
+ -- Has_Prefix --
+ ----------------
+
+ function Has_Prefix (N : Node_Id) return Boolean is
begin
- if Is_Entity_Name (Obj)
- and then Present (Renamed_Entity (Entity (Obj)))
- then
- Obj := Renamed_Entity (Entity (Obj));
- if Nkind (Obj) = N_Explicit_Dereference
- and then Is_Variable (Prefix (Obj))
+ return
+ Nkind_In (N,
+ N_Attribute_Reference,
+ N_Expanded_Name,
+ N_Explicit_Dereference,
+ N_Indexed_Component,
+ N_Reference,
+ N_Selected_Component,
+ N_Slice);
+ end Has_Prefix;
+
+ -----------------
+ -- Is_Renaming --
+ -----------------
+
+ function Is_Renaming (N : Node_Id) return Boolean is
+ begin
+ return Is_Entity_Name (N)
+ and then Present (Renamed_Entity (Entity (N)));
+ end Is_Renaming;
+
+ -----------------------
+ -- Is_Valid_Renaming --
+ -----------------------
+
+ function Is_Valid_Renaming (N : Node_Id) return Boolean is
+
+ function Check_Renaming (N : Node_Id) return Boolean;
+ -- Recursive function used to traverse all the prefixes of N
+
+ function Check_Renaming (N : Node_Id) return Boolean is
+ begin
+ if Is_Renaming (N)
+ and then not Check_Renaming (Renamed_Entity (Entity (N)))
then
- Obj := Empty;
+ return False;
+ end if;
- elsif Nkind (Obj) = N_Indexed_Component then
+ if Nkind (N) = N_Indexed_Component then
declare
Indx : Node_Id;
begin
- Indx := First (Expressions (Obj));
+ Indx := First (Expressions (N));
while Present (Indx) loop
if not Is_OK_Static_Expression (Indx) then
- Obj := Empty;
- exit;
+ return False;
end if;
Next_Index (Indx);
end loop;
end;
end if;
- end if;
- end Check_Renaming;
+
+ if Has_Prefix (N) then
+ declare
+ P : constant Node_Id := Prefix (N);
+
+ begin
+ if Nkind (N) = N_Explicit_Dereference
+ and then Is_Variable (P)
+ then
+ return False;
+
+ elsif Is_Entity_Name (P)
+ and then Ekind (Entity (P)) = E_Function
+ then
+ return False;
+
+ elsif Nkind (P) = N_Function_Call then
+ return False;
+ end if;
+
+ -- Recursion to continue traversing the prefix of the
+ -- renaming expression
+
+ return Check_Renaming (P);
+ end;
+ end if;
+
+ return True;
+ end Check_Renaming;
+
+ -- Start of processing for Is_Valid_Renaming
+
+ begin
+ return Check_Renaming (N);
+ end Is_Valid_Renaming;
-- Start of processing for Denotes_Same_Object
begin
- Check_Renaming (Obj1);
- Check_Renaming (Obj2);
+ -- Both names statically denote the same stand-alone object or parameter
+ -- (RM 6.4.1(6.5/3))
- if No (Obj1)
- or else No (Obj2)
+ if Is_Entity_Name (Obj1)
+ and then Is_Entity_Name (Obj2)
+ and then Entity (Obj1) = Entity (Obj2)
then
- return False;
+ return True;
end if;
- -- If we have entity names, then must be same entity
+ -- For renamings, the prefix of any dereference within the renamed
+ -- object_name is not a variable, and any expression within the
+ -- renamed object_name contains no references to variables nor
+ -- calls on nonstatic functions (RM 6.4.1(6.10/3)).
- if Is_Entity_Name (Obj1) then
- if Is_Entity_Name (Obj2) then
- return Entity (Obj1) = Entity (Obj2);
+ if Is_Renaming (Obj1) then
+ if Is_Valid_Renaming (Obj1) then
+ Obj1 := Renamed_Entity (Entity (Obj1));
else
return False;
end if;
+ end if;
- -- No match if not same node kind
+ if Is_Renaming (Obj2) then
+ if Is_Valid_Renaming (Obj2) then
+ Obj2 := Renamed_Entity (Entity (Obj2));
+ else
+ return False;
+ end if;
+ end if;
+
+ -- No match if not same node kind (such cases are handled by
+ -- Denotes_Same_Prefix)
- elsif Nkind (Obj1) /= Nkind (Obj2) then
+ if Nkind (Obj1) /= Nkind (Obj2) then
return False;
- -- For selected components, must have same prefix and selector
+ -- After handling valid renamings, one of the two names statically
+ -- denoted a renaming declaration whose renamed object_name is known
+ -- to denote the same object as the other (RM 6.4.1(6.10/3))
+
+ elsif Is_Entity_Name (Obj1) then
+ if Is_Entity_Name (Obj2) then
+ return Entity (Obj1) = Entity (Obj2);
+ else
+ return False;
+ end if;
+
+ -- Both names are selected_components, their prefixes are known to
+ -- denote the same object, and their selector_names denote the same
+ -- component (RM 6.4.1(6.6/3)
elsif Nkind (Obj1) = N_Selected_Component then
return Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2))
and then
Entity (Selector_Name (Obj1)) = Entity (Selector_Name (Obj2));
- -- For explicit dereferences, prefixes must be same
+ -- Both names are dereferences and the dereferenced names are known to
+ -- denote the same object (RM 6.4.1(6.7/3))
elsif Nkind (Obj1) = N_Explicit_Dereference then
return Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2));
- -- For indexed components, prefixes and all subscripts must be the same
+ -- Both names are indexed_components, their prefixes are known to denote
+ -- the same object, and each of the pairs of corresponding index values
+ -- are either both static expressions with the same static value or both
+ -- names that are known to denote the same object (RM 6.4.1(6.8/3))
elsif Nkind (Obj1) = N_Indexed_Component then
- if Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2)) then
+ if not Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2)) then
+ return False;
+ else
declare
Indx1 : Node_Id;
Indx2 : Node_Id;
@@ -2924,11 +3025,11 @@ package body Sem_Util is
return True;
end;
- else
- return False;
end if;
- -- For slices, prefixes must match and bounds must match
+ -- Both names are slices, their prefixes are known to denote the same
+ -- object, and the two slices have statically matching index constraints
+ -- (RM 6.4.1(6.9/3))
elsif Nkind (Obj1) = N_Slice
and then Denotes_Same_Object (Prefix (Obj1), Prefix (Obj2))
@@ -2947,10 +3048,11 @@ package body Sem_Util is
and then Denotes_Same_Object (Hi1, Hi2);
end;
- -- Literals will appear as indexes. Isn't this where we should check
- -- Known_At_Compile_Time at least if we are generating warnings ???
+ -- In the recursion, literals appear as indexes.
- elsif Nkind (Obj1) = N_Integer_Literal then
+ elsif Nkind (Obj1) = N_Integer_Literal
+ and then Nkind (Obj2) = N_Integer_Literal
+ then
return Intval (Obj1) = Intval (Obj2);
else
@@ -3014,7 +3116,7 @@ package body Sem_Util is
end loop;
-- If both have the same depth and they do not denote the same
- -- object, they are disjoint and not warning is needed.
+ -- object, they are disjoint and no warning is needed.
if Depth1 = Depth2 then
return False;