[Ada] Types derived from types with foreign conventions

Submitted by Arnaud Charlet on Aug. 2, 2011, 10:06 a.m.


Message ID 20110802100626.GA27234@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet Aug. 2, 2011, 10:06 a.m.
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;

      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);

   --  VN_V_LEVEL : Q_MW_STRING.Bounded_String;  -- workaround


end M_MAIN;

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

2011-08-02  Ed Schonberg  <schonberg@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.

Patch hide | download patch | download mbox

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: