[Ada] Spurious visibility error with nlined subprogram in with-clauses

Arnaud Charlet charlet@adacore.com
Tue Jan 21 08:01:00 GMT 2014


A compilation unit that is a subprogram is rewritten as a package (the wrapper
package) containing the body of the actual subprogram instance. The wrapping
happens when the unit is compiled upon its appearance in the context of some
unit. If it appears in several such contexts, and the subprogram is marked
Inline,  some units only see the wrapper package. Each unit in a context is
made into a visible library unit, and when the unit is the wrapper package, it
is the related instance (the subprogram) that must be made visible. Prior to
this patch, only the converse was done, namely the visible library unit flag
was reset on exit from a given context, but not set when isntalling context.

Executing
     gnatmake -q -gnato -gnatn -gnatwa -gnatQ main
     main

must yield:

     OK

---
with GNAT.IO;  use GNAT.IO;
with Case_Handling_J;
procedure main is
begin
   Put_Line (Case_Handling_J.Get);
end main;
---
with Ada.Containers.Indefinite_Hashed_Maps;
with Ada.Strings.Wide_Wide_Hash;
package Case_Handling is

   S : Wide_Wide_String := "";

private

   type W_Node is record
      Read_Only : Boolean;
   end record;

   package Casing_Exception_Table is new Ada.Containers.Indefinite_Hashed_Maps
     (Key_Type        => Wide_Wide_String,
      Element_Type    => W_Node,
      Hash            => Ada.Strings.Wide_Wide_Hash,
      Equivalent_Keys => "=");
   use Casing_Exception_Table;


end Case_Handling;
---
with Ada.Containers;
package Case_Handling_J is

   function JNI_For_Body_Elaboration return Ada.Containers.Hash_Type;
   function Get return String;

end Case_Handling_J;
---
with Ada.Strings.Wide_Wide_Hash;
with Case_Handling;
package body Case_Handling_J is

   function JNI_For_Body_Elaboration return Ada.Containers.Hash_Type is

   begin
      return Ada.Strings.Wide_Wide_Hash (Case_Handling.S);
   end;

   function Get return String is
   begin
      return "OK";
   end;
end Case_Handling_J;

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

2014-01-21  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch10.adb (Install_Withed_Unit): If the unit is a subprogram
	instance that is inlined, it may have been rewritten as a wrapper
	package. In that case the unit that must be made visible is the
	related instance of the package.

-------------- next part --------------
Index: sem_ch10.adb
===================================================================
--- sem_ch10.adb	(revision 206813)
+++ sem_ch10.adb	(working copy)
@@ -5156,6 +5156,14 @@
 
             Set_Is_Visible_Lib_Unit (Uname);
 
+            --  If the unit is a wrapper package for a compilation unit that is
+            --  a subprogrm instance, indicate that the instance itself is a
+            --  visible unit. This is necessary if the instance is inlined.
+
+            if Is_Wrapper_Package (Uname) then
+               Set_Is_Visible_Lib_Unit (Related_Instance (Uname));
+            end if;
+
             --  If the child unit appears in the context of its parent, it is
             --  immediately visible.
 
@@ -6447,6 +6455,7 @@
 
       --  If the unit is a wrapper package, the subprogram instance is
       --  what must be removed from visibility.
+      --  Should we use Related_Instance instead???
 
       if Is_Wrapper_Package (Unit_Name) then
          Set_Is_Immediately_Visible (Current_Entity (Unit_Name), False);


More information about the Gcc-patches mailing list