A private type may have its convention established by a pragma in the private
part of its enclosing package. A subtype of this type has its convention fixed
at the freeze point. A type derived from this subtype must get its convention
from the base type, because it may be needed in the initialization call for an
object of the derived type.

The following must compile quietly:
     gcc -c -gnatws m_main.adb


with SYSTEM;
procedure M_MAIN is
   package q_mw_string is
      type Sequence is private;
      subtype Bounded_String is Sequence;

   private
      type Sequence is record
         r_array  : string(1 .. 5) := (others => ascii.nul);
      end record;
      pragma Convention(C, Sequence);
   end q_mw_string;

   type T_OPERATOR_LEVEL is new Q_MW_STRING.Bounded_String;
   --  pragma Convention (C, T_Operator_Level);   --  workaround

   V_BUFFER : STRING (1 .. 1000);
   CVN_V_LEVEL_ADDRESS : constant SYSTEM.ADDRESS := V_BUFFER'ADDRESS;
   VN_V_LEVEL : T_OPERATOR_LEVEL;

   --  VN_V_LEVEL : Q_MW_STRING.Bounded_String;  -- workaround

   for VN_V_LEVEL'ADDRESS use CVN_V_LEVEL_ADDRESS;

begin
   null;
end M_MAIN;

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

2011-08-02  Ed Schonberg  <schonb...@adacore.com>

        * sem_ch3.adb (Build_Derived_Type): Inherit the convention from the
        base type, because the parent may be a subtype of a private type whose
        convention is established in a private part.

Index: sem_ch3.adb
===================================================================
--- sem_ch3.adb (revision 177119)
+++ sem_ch3.adb (working copy)
@@ -7836,10 +7836,15 @@
 
       Set_Size_Info      (Derived_Type,                 Parent_Type);
       Set_RM_Size        (Derived_Type, RM_Size        (Parent_Type));
-      Set_Convention     (Derived_Type, Convention     (Parent_Type));
       Set_Is_Controlled  (Derived_Type, Is_Controlled  (Parent_Type));
       Set_Is_Tagged_Type (Derived_Type, Is_Tagged_Type (Parent_Type));
 
+      --  If the parent type is a private subtype, the convention on the base
+      --  type may be set in the private part, and not propagated to the
+      --  subtype until later, so we obtain the convention from the base type.
+
+      Set_Convention     (Derived_Type, Convention     (Parent_Base));
+
       --  Propagate invariant information. The new type has invariants if
       --  they are inherited from the parent type, and these invariants can
       --  be further inherited, so both flags are set.
@@ -9918,9 +9923,10 @@
       Set_Homonym     (Full, Save_Homonym);
       Set_Associated_Node_For_Itype (Full, Related_Nod);
 
-      --  Set common attributes for all subtypes
+      --  Set common attributes for all subtypes: kind, convention, etc.
 
       Set_Ekind (Full, Subtype_Kind (Ekind (Full_Base)));
+      Set_Convention (Full, Convention (Full_Base));
 
       --  The Etype of the full view is inconsistent. Gigi needs to see the
       --  structural full view,  which is what the current scheme gives:

Reply via email to