diff mbox series

[Ada] Spurious error on imported subprogram with precondition

Message ID 20180524130529.GA79023@adacore.com
State New
Headers show
Series [Ada] Spurious error on imported subprogram with precondition | expand

Commit Message

Pierre-Marie de Rodat May 24, 2018, 1:05 p.m. UTC
This patch modifies the generation of wrappers for imported subprograms which
are subject to contracts. In the case of an imported function, the original
function is relocated within the wrapper, and the wrapper simply invokes the
imported subprogram, returning its value. When the result type of the imported
subprogram is anonymous access, the relocation creates a new anonymous access
type, but with a different accessibility level. Since both return types are
essentially the same type, eliminate the accessibility level inconsistency by
unchecked converting the result of calling the imported function to the return
type.

------------
-- Source --
------------

--  pack.ads

package Pack is
   type Integer_Ptr is access all Integer;
   type Typ is null record;

   function Predicate (Val : Typ) return Boolean is (True);

   function Imported_1 (Val : Typ) return access Integer
     with Pre => Predicate (Val), Import;

   function Imported_2 (Val : Typ) return Integer_Ptr
     with Pre => Predicate (Val), Import;
end Pack;

-----------------
-- Compilation --
-----------------

$ gcc -c pack.ads

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

2018-05-24  Hristian Kirtchev  <kirtchev@adacore.com>

gcc/ada/

	* freeze.adb (Wrap_Imported_Subprogram): Generate an unchecked
	conversion to the return type to avoid a side effect where an imported
	relocated function generates a new anonymous access type, whose
	accessibility level does not agree with with that of the wrapper.
diff mbox series

Patch

--- gcc/ada/freeze.adb
+++ gcc/ada/freeze.adb
@@ -5172,13 +5172,24 @@  package body Freeze is
 
             --  Build the call
 
+            --  An imported function whose result type is anonymous access
+            --  creates a new anonynous access type when it is relocated into
+            --  the declarations of the body generated below. As a result, the
+            --  accessibility level of these two anonymous access types may not
+            --  be compatible even though they are essentially the same type.
+            --  Use an unchecked type conversion to reconcile this case. Note
+            --  that the conversion is safe because in the named access type
+            --  case, both the body and imported function utilize the same
+            --  type.
+
             if Ekind_In (E, E_Function, E_Generic_Function) then
                Stmt :=
                  Make_Simple_Return_Statement (Loc,
                    Expression =>
-                     Make_Function_Call (Loc,
-                       Name                   => Make_Identifier (Loc, CE),
-                       Parameter_Associations => Parms));
+                     Unchecked_Convert_To (Etype (E),
+                       Make_Function_Call (Loc,
+                         Name                   => Make_Identifier (Loc, CE),
+                         Parameter_Associations => Parms)));
 
             else
                Stmt :=