We were detecting overlapping actuals in a call like "Proc (A, B, C)"
using two loops that iterated over all parameters, so we were examining
9 pairs:
A-A, A-B, A-C
B-A, B-B, B-C
C-A, C-B, C-C
Now the outer loop iterates over all parameters, while the inner loop
always starts from the next parameter, so we are examining just those
pairs:
___, A-B, A-C
___, ___, B-C
___, ___, ___
which gives the same messages but the code is faster (and cleaner).
Also, there was a yet another loop with a comment "Find matching
actual", which was always assigning Act with Act2 and Form with Form2.
This loop is now entirely removed. Again, messages are the same messages
but the code is faster (and cleaner).
Tested on x86_64-pc-linux-gnu, committed on trunk
2020-06-12 Piotr Trojanek <troja...@adacore.com>
gcc/ada/
* sem_warn.adb (Warn_On_Overlapping_Actuals): Simplify.
--- gcc/ada/sem_warn.adb
+++ gcc/ada/sem_warn.adb
@@ -3750,12 +3750,10 @@ package body Sem_Warn is
null;
else
- Form2 := First_Formal (Subp);
- Act2 := First_Actual (N);
+ Form2 := Next_Formal (Form1);
+ Act2 := Next_Actual (Act1);
while Present (Form2) and then Present (Act2) loop
- if Form1 /= Form2
- and then Refer_Same_Object (Act1, Act2)
- then
+ if Refer_Same_Object (Act1, Act2) then
if Is_Generic_Type (Etype (Act2)) then
return;
end if;
@@ -3847,71 +3845,55 @@ package body Sem_Warn is
or else Error_To_Warning
or else Warn_Only;
- declare
- Act : Node_Id;
- Form : Entity_Id;
-
- begin
- -- Find matching actual
-
- Act := First_Actual (N);
- Form := First_Formal (Subp);
- while Act /= Act2 loop
- Next_Formal (Form);
- Next_Actual (Act);
- end loop;
-
- if Is_Elementary_Type (Etype (Act1))
- and then Ekind (Form2) = E_In_Parameter
- then
- null; -- No real aliasing
-
- elsif Is_Elementary_Type (Etype (Act2))
- and then Ekind (Form2) = E_In_Parameter
- then
- null; -- Ditto
+ if Is_Elementary_Type (Etype (Act1))
+ and then Ekind (Form2) = E_In_Parameter
+ then
+ null; -- No real aliasing
- -- If the call was written in prefix notation, and
- -- thus its prefix before rewriting was a selected
- -- component, count only visible actuals in call.
+ elsif Is_Elementary_Type (Etype (Act2))
+ and then Ekind (Form2) = E_In_Parameter
+ then
+ null; -- Ditto
- elsif Is_Entity_Name (First_Actual (N))
- and then Nkind (Original_Node (N)) = Nkind (N)
- and then Nkind (Name (Original_Node (N))) =
- N_Selected_Component
- and then
- Is_Entity_Name
- (Prefix (Name (Original_Node (N))))
- and then
- Entity (Prefix (Name (Original_Node (N)))) =
- Entity (First_Actual (N))
- then
- if Act1 = First_Actual (N) then
- Error_Msg_FE
- ("<<`IN OUT` prefix overlaps with "
- & "actual for&", Act1, Form);
+ -- If the call was written in prefix notation, and
+ -- thus its prefix before rewriting was a selected
+ -- component, count only visible actuals in call.
- else
- -- For greater clarity, give name of formal
-
- Error_Msg_Node_2 := Form;
- Error_Msg_FE
- ("<<writable actual for & overlaps with "
- & "actual for&", Act1, Form);
- end if;
+ elsif Is_Entity_Name (First_Actual (N))
+ and then Nkind (Original_Node (N)) = Nkind (N)
+ and then Nkind (Name (Original_Node (N))) =
+ N_Selected_Component
+ and then
+ Is_Entity_Name (Prefix (Name (Original_Node (N))))
+ and then
+ Entity (Prefix (Name (Original_Node (N)))) =
+ Entity (First_Actual (N))
+ then
+ if Act1 = First_Actual (N) then
+ Error_Msg_FE
+ ("<<`IN OUT` prefix overlaps with "
+ & "actual for&", Act1, Form2);
else
-- For greater clarity, give name of formal
- Error_Msg_Node_2 := Form;
-
- -- This is one of the messages
-
+ Error_Msg_Node_2 := Form2;
Error_Msg_FE
("<<writable actual for & overlaps with "
- & "actual for&", Act1, Form1);
+ & "actual for&", Act1, Form2);
end if;
- end;
+
+ else
+ -- For greater clarity, give name of formal
+
+ Error_Msg_Node_2 := Form2;
+
+ -- This is one of the messages
+
+ Error_Msg_FE
+ ("<<writable actual for & overlaps with "
+ & "actual for&", Act1, Form1);
+ end if;
end if;
end if;