Patchwork [Ada] Overriding indicator rejected for controlled operation in child unit

login
register
mail settings
Submitter Arnaud Charlet
Date June 14, 2010, 1:46 p.m.
Message ID <20100614134659.GA12650@adacore.com>
Download mbox | patch
Permalink /patch/55533/
State New
Headers show

Comments

Arnaud Charlet - June 14, 2010, 1:46 p.m.
The compiler rejects an overriding indicator on a controlled operation
declared within a child unit's private part for a full type that inherits
the controlled operation as a hidden operation in its partial view.
When checking legality of overriding indicators, the test for whether
the overridden subprogram is hidden doesn't apply in general for
controlled operations, because those are marked as hidden when inherited
by a private extension from a type that declares them in a private part.
The problem is that they never become unhidden, even when the full type
has visibility of their parent subprogram, as can occur within a child
unit. This is corrected by adding a test of whether the parent subprogram
of the overridden subprogram is itself hidden, in the specific case where
the subprograms are controlled operations.

Child package priv_controlled-override.adb must compile quietly with -gnat05:


with Ada.Finalization;

package Priv_Controlled is

   type Privately_Controlled is tagged private;

private

   type Privately_Controlled is
     new Ada.Finalization.Controlled with null record;

   overriding procedure Finalize (Self : in out Privately_Controlled);

end Priv_Controlled;

package Priv_Controlled.Override is

   type Other_Priv_Controlled is new Privately_Controlled with private;

private

   type Other_Priv_Controlled is new Privately_Controlled with null record;

   overriding procedure Finalize (Self : in out Other_Priv_Controlled);

end Priv_Controlled.Override;

package body Priv_Controlled.Override is

   overriding procedure Finalize (Self : in out Other_Priv_Controlled) is
   begin
      null;
   end Finalize;

end Priv_Controlled.Override;

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

2010-06-14  Gary Dismukes  <dismukes@adacore.com>

	* sem_ch6.adb (Check_Overriding_Indicator): Add a special check for
	controlled operations, so that they will be treated as overriding even
	if the overridden subprogram is marked Is_Hidden, as long as the
	overridden subprogram's parent subprogram is not hidden.

Patch

Index: sem_ch6.adb
===================================================================
--- sem_ch6.adb	(revision 160723)
+++ sem_ch6.adb	(working copy)
@@ -4420,8 +4420,24 @@  package body Sem_Ch6 is
          end;
       end if;
 
+      --  If there is an overridden subprogram, then check that there is not
+      --  a "not overriding" indicator, and mark the subprogram as overriding.
+      --  This is not done if the overridden subprogram is marked as hidden,
+      --  which can occur for the case of inherited controlled operations
+      --  (see Derive_Subprogram), unless the inherited subprogram's parent
+      --  subprogram is not itself hidden. (Note: This condition could probably
+      --  be simplified, leaving out the testing for the specific controlled
+      --  cases, but it seems safer and clearer this way, and echoes similar
+      --  special-case tests of this kind in other places.)
+
       if Present (Overridden_Subp)
-        and then not Is_Hidden (Overridden_Subp)
+        and then (not Is_Hidden (Overridden_Subp)
+                   or else
+                     ((Chars (Overridden_Subp) = Name_Initialize
+                         or else Chars (Overridden_Subp) = Name_Adjust
+                         or else Chars (Overridden_Subp) = Name_Finalize)
+                       and then Present (Alias (Overridden_Subp))
+                       and then not Is_Hidden (Alias (Overridden_Subp))))
       then
          if Must_Not_Override (Spec) then
             Error_Msg_Sloc := Sloc (Overridden_Subp);