[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