public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Ada] Spurious error in dispatching call with class-wide precondition
@ 2019-08-20  9:51 Pierre-Marie de Rodat
  0 siblings, 0 replies; only message in thread
From: Pierre-Marie de Rodat @ 2019-08-20  9:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: Ed Schonberg

[-- Attachment #1: Type: text/plain, Size: 1061 bytes --]

This patch fixes a spurious visibility error on a dispatching call to
a subprogram with a classwide precondition, when the call qppears in
the same declarative part as the subprogram declaration itself.

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

2019-08-20  Ed Schonberg  <schonberg@adacore.com>

gcc/ada/

	* exp_disp.adb (Build_Class_Wide_Check, Replace_Formals): When a
	dispatching call tp a subprogram with a class-wide precondition
	occurrs in the same declarative part as the ancestor subprogram
	being called, the`expression for the precondition has not been
	analyzed yet. Such a call may appear, e.g. in an expression
	function. In that case, the replacement of formals by actuals in
	the call cannot use the formal entities of the subprogram being
	called, and the occurrence of the formals in the expression must
	be located by name (Chars fields) as would be done at a later
	freeze point, when the expression is resolved in the context of
	the subprogram itself.

gcc/testsuite/

	* gnat.dg/tagged5.adb, gnat.dg/tagged5.ads: New testcase.

[-- Attachment #2: patch.diff --]
[-- Type: text/x-diff, Size: 3202 bytes --]

--- gcc/ada/exp_disp.adb
+++ gcc/ada/exp_disp.adb
@@ -728,23 +728,27 @@ package body Exp_Disp is
          --  corresponding actuals in the call, given that this check is
          --  performed outside of the body of the subprogram.
 
+         --  If the dispatching call appears in the same scope as the
+         --  declaration of the dispatching subprogram (for example in
+         --  the expression of a local expression function) the prec.
+         --  has not been analyzed yet, in which case we use the Chars
+         --  field to recognize intended occurrences of the formals.
+
          ---------------------
          -- Replace_Formals --
          ---------------------
 
          function Replace_Formals (N : Node_Id) return Traverse_Result is
+            A : Node_Id;
+            F : Entity_Id;
          begin
-            if Is_Entity_Name (N)
-              and then Present (Entity (N))
-              and then Is_Formal (Entity (N))
-            then
-               declare
-                  A : Node_Id;
-                  F : Entity_Id;
+            if Is_Entity_Name (N) then
+               F := First_Formal (Subp);
+               A := First_Actual (Call_Node);
 
-               begin
-                  F := First_Formal (Subp);
-                  A := First_Actual (Call_Node);
+               if Present (Entity (N))
+                 and then Is_Formal (Entity (N))
+               then
                   while Present (F) loop
                      if F = Entity (N) then
                         Rewrite (N, New_Copy_Tree (A));
@@ -776,7 +780,25 @@ package body Exp_Disp is
                      Next_Formal (F);
                      Next_Actual (A);
                   end loop;
-               end;
+
+               --  If node is not analyzed, recognize occurrences of
+               --  a formal by name, as would be done when resolving
+               --  the aspect expression in the context of the subprogram.
+
+               elsif not Analyzed (N)
+                 and then Nkind (N) = N_Identifier
+                 and then No (Entity (N))
+               then
+                  while Present (F) loop
+                     if Chars (N) = Chars (F) then
+                        Rewrite (N, New_Copy_Tree (A));
+                        return Skip;
+                     end if;
+
+                     Next_Formal (F);
+                     Next_Actual (A);
+                  end loop;
+               end if;
             end if;
 
             return OK;

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/tagged5.adb
@@ -0,0 +1,6 @@
+--  { dg-do compile }
+--  { dg-options "-gnata" }
+
+package body Tagged5 is
+   procedure Dummy is null;
+end Tagged5;

--- /dev/null
new file mode 100644
+++ gcc/testsuite/gnat.dg/tagged5.ads
@@ -0,0 +1,18 @@
+package Tagged5 is
+
+    type T is limited interface;
+
+    not overriding function Element
+      (Self  : T;
+       Index : Positive)
+       return Integer is abstract
+       with Pre'Class => Index + Index ** 2 in 1 .. 10;
+
+    function First
+      (Self  : T'Class)
+       return Integer
+         is (Self.Element (1));
+
+    procedure Dummy;
+
+end Tagged5;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-08-20  9:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-20  9:51 [Ada] Spurious error in dispatching call with class-wide precondition Pierre-Marie de Rodat

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).