[Ada] Additional warnings on overlapping actuals of composite types

Message ID 20200610133540.GA80757@adacore.com
State New
Headers show
Series
  • [Ada] Additional warnings on overlapping actuals of composite types
Related show

Commit Message

Pierre-Marie de Rodat June 10, 2020, 1:35 p.m.
This patch enhances the warnings on overlapping actuals of composite
types when only one of them is writable. If these parameters are passed
by reference it is the case that assignment to one could have the
undesirable effect of modifying the other inside the called subprogram.

Tested on x86_64-pc-linux-gnu, committed on trunk

2020-06-10  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

	* sem_warn.adb (Warn_On_Overlapping_Actuals): Add a warning when
	two actuals in a call overlap, both are composite types that may
	be passed by reference, and only one of them is writable.

Patch

--- gcc/ada/sem_warn.adb
+++ gcc/ada/sem_warn.adb
@@ -3742,10 +3742,26 @@  package body Sem_Warn is
       --  If appropriate warning switch is set, we also report warnings on
       --  overlapping parameters that are record types or array types.
 
+      --  It is also worthwhile to warn on overlaps of composite objects when
+      --  only one of the formals is (in)-out.  Note that the RM rule above is
+      --  a legality rule. We choose to implement this check as a warning to
+      --  avoid major incompatibilities with legacy code. We exclude internal
+      --  sources from the warning, because subprograms in Container libraries
+      --  would be affected by the warning.
+
+      --  Note also that the rule in 6.4.1 (6.17/3), introduced by AI12-0324,
+      --  is potentially more expensive to verify, and is not yet implemented.
+
+      if Is_Internal_Unit (Current_Sem_Unit) then
+         return;
+      end if;
+
       Form1 := First_Formal (Subp);
       Act1  := First_Actual (N);
       while Present (Form1) and then Present (Act1) loop
-         if Is_Covered_Formal (Form1) then
+         if Is_Covered_Formal (Form1)
+            or else not Is_Elementary_Type (Etype (Act1))
+         then
             Form2 := First_Formal (Subp);
             Act2  := First_Actual (N);
             while Present (Form2) and then Present (Act2) loop