diff mbox

[Ada] Spurious visibility error with private subtye, inlining and instance

Message ID 20151118102314.GA70891@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Nov. 18, 2015, 10:23 a.m. UTC
This patch fixes an oversight in the restoring of proper use visibility on
the full view of a private subtype, when a use clause for the enclosing
package appears before an instantiation of a child unit of the package, the
instantiation is followed by a use of the private subtype, and the compilation
has inlining enabled.

The following must compile quietly;

   gcc -c -gnatn p.adb

---
with Q; use Q;
with S.Data;

package body P is

   package My_Data is new S.Data (Integer);

   procedure Process_Commands (Commands : S.Symbol_Ref) is
     Ret : constant S.Symbol_Ref := Func (Commands);
   begin
     null;
   end;

end P;
---
with S;

package P is

   procedure Process_Commands (Commands : S.Symbol_Ref);

end P;
---
with R; use R;

package body Q is

  function Func (Symbol : S.Symbol_Ref) return S.Symbol_Ref is
    procedure Do_Query is new Query (0);
  begin
    return Symbol;
  end;

end Q;
---
with S;

package Q is

  function Func (Symbol : S.Symbol_Ref) return S.Symbol_Ref;
  pragma Inline (Func);

end Q;
---
with S.Data;

package body R is

   use S;

   package My_Data is new S.Data (Integer);

   procedure Query (Symbol : Not_Null_Symbol_Ref) is
   begin
      null;
   end;

end R;
---
with S;

package R is

   generic
      I : Integer;
   procedure Query (Symbol : S.Not_Null_Symbol_Ref);

end R;
---
private with T;

package S is

   type Symbol_Ref is private;

   subtype Not_Null_Symbol_Ref is Symbol_Ref;

private

   type Symbol_Ref is new T.Pointer_Type;

end S;
---
package body T is

   package body Define_Field is

      function Access_Field (Object : Pointer_Type) return access Field_Type is
      begin
         return null;
      end Access_Field;

   end Define_Field;

end T;
---
package T is

   type Pointer_Type is private;

   generic
      type Field_Type is limited private;
   package Define_Field is
      function Access_Field (Object : Pointer_Type) return access Field_Type;
   end Define_Field;

private

   type Pointer_Type is access Integer;

end T;
---
package body S.Data is

   package My_Field is new T.Define_Field (Data_Type);

   function Access_Data (Symbol : Symbol_Ref) return access Data_Type is
      Pointer : constant T.Pointer_Type := T.Pointer_Type (Symbol);
   begin
      return My_Field.Access_Field (Pointer);
   end Access_Data;

end S.Data;
---
generic
   type Data_Type is limited private;
package S.Data is

   function Access_Data (Symbol : Symbol_Ref) return access Data_Type;

end S.Data;

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

2015-11-18  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch7.adb (Uninstall_Declarations): Before swapping private
	and full views, ensure that the potential use visbility of the
	two views is consistent.
diff mbox

Patch

Index: sem_ch7.adb
===================================================================
--- sem_ch7.adb	(revision 230522)
+++ sem_ch7.adb	(working copy)
@@ -2675,10 +2675,13 @@ 
          --  If this is a private type with a full view (for example a local
          --  subtype of a private type declared elsewhere), ensure that the
          --  full view is also removed from visibility: it may be exposed when
-         --  swapping views in an instantiation.
+         --  swapping views in an instantiation. Similarly, ensure that the
+         --  use-visibility is properly set on both views.
 
          if Is_Type (Id) and then Present (Full_View (Id)) then
-            Set_Is_Immediately_Visible (Full_View (Id), False);
+            Set_Is_Immediately_Visible     (Full_View (Id), False);
+            Set_Is_Potentially_Use_Visible (Full_View (Id),
+              Is_Potentially_Use_Visible (Id));
          end if;
 
          if Is_Tagged_Type (Id) and then Ekind (Id) = E_Record_Type then