gigi.h (build_simple_component_ref): Declare.
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 1 Jun 2015 07:43:09 +0000 (07:43 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 1 Jun 2015 07:43:09 +0000 (07:43 +0000)
* gcc-interface/gigi.h (build_simple_component_ref): Declare.
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Deal with
address clause on aliased object with unconstrained nominal subtype.
Mark the aligning variable as artificial, do not convert the address
expression immediately but mark it as constant instead.
* gcc-interface/utils.c (convert): If the target type contains a
template, be prepared for an empty array.
(maybe_unconstrained_array): Likewise.
* gcc-interface/utils2.c (known_alignment) <POINTER_PLUS_EXPR>: Deal
with the pattern built for aligning types.
<INTEGER_CST>: Do not cap the value at BIGGEST_ALIGNMENT.
(build_simple_component_ref): Make public.
If the base object is a constructor that contains a template, fold the
result field by field.

From-SVN: r223912

gcc/ada/ChangeLog
gcc/ada/gcc-interface/decl.c
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/utils.c
gcc/ada/gcc-interface/utils2.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/addr9_1.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/addr9_2.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/addr9_3.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/addr9_4.adb [new file with mode: 0644]

index ca8f0f3f0737f50a5dc1de4f16ad9239ba32f92a..a2887e88b0e9fbc52eba72b572596f20c0840b37 100644 (file)
@@ -1,3 +1,20 @@
+2015-06-01  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/gigi.h (build_simple_component_ref): Declare.
+       * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Deal with
+       address clause on aliased object with unconstrained nominal subtype.
+       Mark the aligning variable as artificial, do not convert the address
+       expression immediately but mark it as constant instead.
+       * gcc-interface/utils.c (convert): If the target type contains a
+       template, be prepared for an empty array.
+       (maybe_unconstrained_array): Likewise.
+       * gcc-interface/utils2.c (known_alignment) <POINTER_PLUS_EXPR>: Deal
+       with the pattern built for aligning types.
+       <INTEGER_CST>: Do not cap the value at BIGGEST_ALIGNMENT.
+       (build_simple_component_ref): Make public.
+       If the base object is a constructor that contains a template, fold the
+       result field by field.
+
 2015-05-31  Eric Botcazou  <ebotcazou@adacore.com>
 
        * s-oscons-tmplt.c: Add explicit tests for Android alongside Linux.
index 0142e8e56b36cf5234d8f224da2f8cb2309f44c9..966bf8e1309e3cabcc73f2e36ad79fe102e78b99 100644 (file)
@@ -882,8 +882,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
            check_ok_for_atomic_type (gnu_inner, gnat_entity, true);
          }
 
-       /* If this is an aliased object with an unconstrained nominal subtype,
-          make a type that includes the template.  */
+       /* If this is an aliased object with an unconstrained array nominal
+          subtype, make a type that includes the template.  We will either
+          allocate or create a variable of that type, see below.  */
        if (Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity))
            && Is_Array_Type (Underlying_Type (Etype (gnat_entity)))
            && !type_annotate_only)
@@ -1149,7 +1150,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
           effects in this case.  */
        if (definition && Present (Address_Clause (gnat_entity)))
          {
-           Node_Id gnat_expr = Expression (Address_Clause (gnat_entity));
+           const Node_Id gnat_clause = Address_Clause (gnat_entity);
+           Node_Id gnat_expr = Expression (gnat_clause);
            tree gnu_address
              = present_gnu_tree (gnat_entity)
                ? get_gnu_tree (gnat_entity) : gnat_to_gnu (gnat_expr);
@@ -1167,6 +1169,40 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                || compile_time_known_address_p (gnat_expr);
            gnu_size = NULL_TREE;
 
+           /* If this is an aliased object with an unconstrained array nominal
+              subtype, then it can overlay only another aliased object with an
+              unconstrained array nominal subtype and compatible template.  */
+           if (Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity))
+               && Is_Array_Type (Underlying_Type (Etype (gnat_entity)))
+               && !type_annotate_only)
+             {
+               tree rec_type = TREE_TYPE (gnu_type);
+               tree off = byte_position (DECL_CHAIN (TYPE_FIELDS (rec_type)));
+
+               /* This is the pattern built for a regular object.  */
+               if (TREE_CODE (gnu_address) == POINTER_PLUS_EXPR
+                   && TREE_OPERAND (gnu_address, 1) == off)
+                 gnu_address = TREE_OPERAND (gnu_address, 0);
+               /* This is the pattern built for an overaligned object.  */
+               else if (TREE_CODE (gnu_address) == POINTER_PLUS_EXPR
+                        && TREE_CODE (TREE_OPERAND (gnu_address, 1))
+                           == PLUS_EXPR
+                        && TREE_OPERAND (TREE_OPERAND (gnu_address, 1), 1)
+                           == off)
+                 gnu_address
+                   = build2 (POINTER_PLUS_EXPR, gnu_type,
+                             TREE_OPERAND (gnu_address, 0),
+                             TREE_OPERAND (TREE_OPERAND (gnu_address, 1), 0));
+               else
+                 {
+                   post_error_ne ("aliased object& with unconstrained array "
+                                  "nominal subtype", gnat_clause,
+                                  gnat_entity);
+                   post_error ("\\can overlay only aliased object with "
+                               "compatible subtype", gnat_clause);
+                 }
+             }
+
            /* If this is a deferred constant, the initializer is attached to
               the full view.  */
            if (kind == E_Constant && Present (Full_View (gnat_entity)))
@@ -1183,11 +1219,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
            else
              gnu_expr
                = build2 (COMPOUND_EXPR, gnu_type,
-                         build_binary_op
-                         (MODIFY_EXPR, NULL_TREE,
-                          build_unary_op (INDIRECT_REF, NULL_TREE,
-                                          gnu_address),
-                          gnu_expr),
+                         build_binary_op (INIT_EXPR, NULL_TREE,
+                                          build_unary_op (INDIRECT_REF,
+                                                          NULL_TREE,
+                                                          gnu_address),
+                                          gnu_expr),
                          gnu_address);
          }
 
@@ -1302,8 +1338,11 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
        /* If this object would go into the stack and has an alignment larger
           than the largest stack alignment the back-end can honor, resort to
           a variable of "aligning type".  */
-       if (!global_bindings_p () && !static_p && definition
-           && !imported_p && TYPE_ALIGN (gnu_type) > BIGGEST_ALIGNMENT)
+       if (definition
+           && !global_bindings_p ()
+           && !static_p
+           && !imported_p
+           && TYPE_ALIGN (gnu_type) > BIGGEST_ALIGNMENT)
          {
            /* Create the new variable.  No need for extra room before the
               aligned field as this is in automatic storage.  */
@@ -1315,11 +1354,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
              = create_var_decl (create_concat_name (gnat_entity, "ALIGN"),
                                 NULL_TREE, gnu_new_type, NULL_TREE, false,
                                 false, false, false, NULL, gnat_entity);
+           DECL_ARTIFICIAL (gnu_new_var) = 1;
 
            /* Initialize the aligned field if we have an initializer.  */
            if (gnu_expr)
              add_stmt_with_node
-               (build_binary_op (MODIFY_EXPR, NULL_TREE,
+               (build_binary_op (INIT_EXPR, NULL_TREE,
                                  build_component_ref
                                  (gnu_new_var, NULL_TREE,
                                   TYPE_FIELDS (gnu_new_type), false),
@@ -1330,28 +1370,26 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
            gnu_type = build_reference_type (gnu_type);
            gnu_expr
              = build_unary_op
-               (ADDR_EXPR, gnu_type,
+               (ADDR_EXPR, NULL_TREE,
                 build_component_ref (gnu_new_var, NULL_TREE,
                                      TYPE_FIELDS (gnu_new_type), false));
+           TREE_CONSTANT (gnu_expr) = 1;
 
            used_by_ref = true;
            const_flag = true;
            gnu_size = NULL_TREE;
          }
 
-       /* If this is an aliased object with an unconstrained nominal subtype,
-          we make its type a thin reference, i.e. the reference counterpart
-          of a thin pointer, so that it points to the array part.  This is
-          aimed at making it easier for the debugger to decode the object.
-          Note that we have to do that this late because of the couple of
-          allocation adjustments that might be made just above.  */
+       /* If this is an aliased object with an unconstrained array nominal
+          subtype, we make its type a thin reference, i.e. the reference
+          counterpart of a thin pointer, so it points to the array part.
+          This is aimed to make it easier for the debugger to decode the
+          object.  Note that we have to do it this late because of the
+          couple of allocation adjustments that might be made above.  */
        if (Is_Constr_Subt_For_UN_Aliased (Etype (gnat_entity))
            && Is_Array_Type (Underlying_Type (Etype (gnat_entity)))
            && !type_annotate_only)
          {
-           tree gnu_array
-             = gnat_to_gnu_type (Base_Type (Etype (gnat_entity)));
-
            /* In case the object with the template has already been allocated
               just above, we have nothing to do here.  */
            if (!TYPE_IS_THIN_POINTER_P (gnu_type))
@@ -1362,8 +1400,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                                      const_flag, Is_Public (gnat_entity),
                                      imported_p || !definition, static_p,
                                      NULL, gnat_entity);
-               gnu_expr
-                 = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_unc_var);
+               gnu_expr = build_unary_op (ADDR_EXPR, NULL_TREE, gnu_unc_var);
                TREE_CONSTANT (gnu_expr) = 1;
 
                used_by_ref = true;
@@ -1372,6 +1409,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
                gnu_size = NULL_TREE;
              }
 
+           tree gnu_array
+             = gnat_to_gnu_type (Base_Type (Etype (gnat_entity)));
            gnu_type
              = build_reference_type (TYPE_OBJECT_RECORD_TYPE (gnu_array));
          }
index 65f871bf89594defc6c640a53ea04d623f2ef75b..91d9f9cfb581ae5a35b8f96e6db8e1c6f5c1e71e 100644 (file)
@@ -914,6 +914,11 @@ extern tree gnat_build_constructor (tree type, vec<constructor_elt, va_gc> *v);
 /* Return a COMPONENT_REF to access a field that is given by COMPONENT,
    an IDENTIFIER_NODE giving the name of the field, FIELD, a FIELD_DECL,
    for the field, or both.  Don't fold the result if NO_FOLD_P.  */
+extern tree build_simple_component_ref (tree record_variable, tree component,
+                                       tree field, bool no_fold_p);
+
+/* Likewise, but generate a Constraint_Error if the reference could not be
+   found.  */
 extern tree build_component_ref (tree record_variable, tree component,
                                  tree field, bool no_fold_p);
 
index 0871c3cbe3b48c6c3f4d81ffdd69517f8e10dc47..31bb3d254ed914937e583988d44867f2fb9a917e 100644 (file)
@@ -4092,8 +4092,9 @@ convert (tree type, tree expr)
       CONSTRUCTOR_APPEND_ELT (v, TYPE_FIELDS (type),
                              build_template (TREE_TYPE (TYPE_FIELDS (type)),
                                              obj_type, NULL_TREE));
-      CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (type)),
-                             convert (obj_type, expr));
+      if (expr)
+       CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (type)),
+                               convert (obj_type, expr));
       return gnat_build_constructor (type, v);
     }
 
@@ -4699,14 +4700,13 @@ maybe_unconstrained_array (tree exp)
 
       if (TYPE_CONTAINS_TEMPLATE_P (type))
        {
-         exp = build_component_ref (exp, NULL_TREE,
-                                    DECL_CHAIN (TYPE_FIELDS (type)),
-                                    false);
-         type = TREE_TYPE (exp);
+         exp = build_simple_component_ref (exp, NULL_TREE,
+                                           DECL_CHAIN (TYPE_FIELDS (type)),
+                                           false);
 
          /* If the array type is padded, convert to the unpadded type.  */
-         if (TYPE_IS_PADDING_P (type))
-           exp = convert (TREE_TYPE (TYPE_FIELDS (type)), exp);
+         if (exp && TYPE_IS_PADDING_P (TREE_TYPE (exp)))
+           exp = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (exp))), exp);
        }
       break;
 
index cc2c645ff4886aa741e8861ee60da01b8fab2fc2..12d9ea95d7cbe0f00b417f083dea2ea7159572a2 100644 (file)
@@ -78,9 +78,9 @@ get_base_type (tree type)
   return type;
 }
 \f
-/* EXP is a GCC tree representing an address.  See if we can find how
-   strictly the object at that address is aligned.   Return that alignment
-   in bits.  If we don't know anything about the alignment, return 0.  */
+/* EXP is a GCC tree representing an address.  See if we can find how strictly
+   the object at this address is aligned and, if so, return the alignment of
+   the object in bits.  Otherwise return 0.  */
 
 unsigned int
 known_alignment (tree exp)
@@ -99,13 +99,13 @@ known_alignment (tree exp)
       break;
 
     case COMPOUND_EXPR:
-      /* The value of a COMPOUND_EXPR is that of it's second operand.  */
+      /* The value of a COMPOUND_EXPR is that of its second operand.  */
       this_alignment = known_alignment (TREE_OPERAND (exp, 1));
       break;
 
     case PLUS_EXPR:
     case MINUS_EXPR:
-      /* If two address are added, the alignment of the result is the
+      /* If two addresses are added, the alignment of the result is the
         minimum of the two alignments.  */
       lhs = known_alignment (TREE_OPERAND (exp, 0));
       rhs = known_alignment (TREE_OPERAND (exp, 1));
@@ -113,10 +113,20 @@ known_alignment (tree exp)
       break;
 
     case POINTER_PLUS_EXPR:
-      lhs = known_alignment (TREE_OPERAND (exp, 0));
-      rhs = known_alignment (TREE_OPERAND (exp, 1));
+      /* If this is the pattern built for aligning types, decode it.  */
+      if (TREE_CODE (TREE_OPERAND (exp, 1)) == BIT_AND_EXPR
+         && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 1), 0)) == NEGATE_EXPR)
+       {
+         tree op = TREE_OPERAND (TREE_OPERAND (exp, 1), 1);
+         return
+           known_alignment (fold_build1 (BIT_NOT_EXPR, TREE_TYPE (op), op));
+       }
+
       /* If we don't know the alignment of the offset, we assume that
         of the base.  */
+      lhs = known_alignment (TREE_OPERAND (exp, 0));
+      rhs = known_alignment (TREE_OPERAND (exp, 1));
+
       if (rhs == 0)
        this_alignment = lhs;
       else
@@ -124,7 +134,7 @@ known_alignment (tree exp)
       break;
 
     case COND_EXPR:
-      /* If there is a choice between two values, use the smallest one.  */
+      /* If there is a choice between two values, use the smaller one.  */
       lhs = known_alignment (TREE_OPERAND (exp, 1));
       rhs = known_alignment (TREE_OPERAND (exp, 2));
       this_alignment = MIN (lhs, rhs);
@@ -135,7 +145,7 @@ known_alignment (tree exp)
        unsigned HOST_WIDE_INT c = TREE_INT_CST_LOW (exp);
        /* The first part of this represents the lowest bit in the constant,
           but it is originally in bytes, not bits.  */
-       this_alignment = MIN (BITS_PER_UNIT * (c & -c), BIGGEST_ALIGNMENT);
+       this_alignment = (c & -c) * BITS_PER_UNIT;
       }
       break;
 
@@ -172,7 +182,7 @@ known_alignment (tree exp)
          return known_alignment (t);
       }
 
-      /* Fall through... */
+      /* ... fall through ... */
 
     default:
       /* For other pointer expressions, we assume that the pointed-to object
@@ -1990,7 +2000,7 @@ gnat_build_constructor (tree type, vec<constructor_elt, va_gc> *v)
    We also handle the fact that we might have been passed a pointer to the
    actual record and know how to look for fields in variant parts.  */
 
-static tree
+tree
 build_simple_component_ref (tree record_variable, tree component, tree field,
                            bool no_fold_p)
 {
@@ -2128,18 +2138,26 @@ build_simple_component_ref (tree record_variable, tree component, tree field,
   if (TREE_CODE (base) == CONSTRUCTOR
       && TYPE_CONTAINS_TEMPLATE_P (TREE_TYPE (base)))
     {
-      vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (base);
-      unsigned HOST_WIDE_INT idx;
-      tree index, value;
-      FOR_EACH_CONSTRUCTOR_ELT (elts, idx, index, value)
-       if (index == field)
-         return value;
+      unsigned int len = CONSTRUCTOR_NELTS (base);
+      gcc_assert (len > 0);
+
+      if (field == CONSTRUCTOR_ELT (base, 0)->index)
+       return CONSTRUCTOR_ELT (base, 0)->value;
+
+      if (len > 1)
+       {
+         if (field == CONSTRUCTOR_ELT (base, 1)->index)
+           return CONSTRUCTOR_ELT (base, 1)->value;
+       }
+      else
+       return NULL_TREE;
+
       return ref;
     }
 
   return fold (ref);
 }
-\f
+
 /* Likewise, but generate a Constraint_Error if the reference could not be
    found.  */
 
index 7d9e46da773a6a08acef568c83e046fc06fa3940..3cafd133bc5a9cfec699efb5ec98a31f74f57a7d 100644 (file)
@@ -1,3 +1,10 @@
+2015-06-01  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/addr9_1.adb: New test.
+       * gnat.dg/addr9_2.adb: Likewise.
+       * gnat.dg/addr9_3.adb: Likewise.
+       * gnat.dg/addr9_4.adb: Likewise.
+
 2015-05-31  Eric Botcazou  <ebotcazou@adacore.com>
 
          * g++.dg/other/dump-ada-spec-4.C: New test.
diff --git a/gcc/testsuite/gnat.dg/addr9_1.adb b/gcc/testsuite/gnat.dg/addr9_1.adb
new file mode 100644 (file)
index 0000000..d3fc335
--- /dev/null
@@ -0,0 +1,40 @@
+-- { dg-do compile }\r
+\r
+with Ada.Streams; use Ada.Streams;\r
+\r
+procedure Addr9_1 is\r
+\r
+   type Signal_Type is mod 2 ** 16;\r
+\r
+   type A_Item is record\r
+      I : Signal_Type;\r
+      Q : Signal_Type;\r
+   end record\r
+   with Size => 32;\r
+\r
+   for A_Item use record\r
+      I at 0 range 0 .. 15;\r
+      Q at 2 range 0 .. 15;\r
+   end record;\r
+\r
+   type A_Array_Type is\r
+     array (Positive range <>)\r
+     of A_Item\r
+   with Alignment => 16;\r
+\r
+   pragma Pack (A_Array_Type);\r
+\r
+   type B_Array_Type is new Ada.Streams.Stream_Element_Array\r
+   with Alignment => 16;\r
+\r
+   Ct_Count : constant := 7_000;\r
+\r
+   package Set is\r
+      A : aliased A_Array_Type := (1 .. Ct_Count => <>);\r
+      B : aliased B_Array_Type := (1 .. Ct_Count * A_Item'Size / 8 => <>);\r
+      for B'Address use A'Address;\r
+   end Set;\r
+\r
+begin\r
+   null;\r
+end;\r
diff --git a/gcc/testsuite/gnat.dg/addr9_2.adb b/gcc/testsuite/gnat.dg/addr9_2.adb
new file mode 100644 (file)
index 0000000..64130e2
--- /dev/null
@@ -0,0 +1,40 @@
+-- { dg-do compile }\r
+\r
+with Ada.Streams; use Ada.Streams;\r
+\r
+procedure Addr9_2 is\r
+\r
+   type Signal_Type is mod 2 ** 16;\r
+\r
+   type A_Item is record\r
+      I : Signal_Type;\r
+      Q : Signal_Type;\r
+   end record\r
+   with Size => 32;\r
+\r
+   for A_Item use record\r
+      I at 0 range 0 .. 15;\r
+      Q at 2 range 0 .. 15;\r
+   end record;\r
+\r
+   type A_Array_Type is\r
+     array (Positive range <>)\r
+     of A_Item\r
+   with Alignment => 16;\r
+\r
+   pragma Pack (A_Array_Type);\r
+\r
+   type B_Array_Type is new Ada.Streams.Stream_Element_Array\r
+   with Alignment => 16;\r
+\r
+   Ct_Count : constant := 7_000;\r
+\r
+   package Set is\r
+      A : A_Array_Type := (1 .. Ct_Count => <>);\r
+      B : aliased B_Array_Type := (1 .. Ct_Count * A_Item'Size / 8 => <>);\r
+      for B'Address use A'Address; -- { dg-warning "aliased object" }\r
+   end Set;\r
+\r
+begin\r
+   null;\r
+end;\r
diff --git a/gcc/testsuite/gnat.dg/addr9_3.adb b/gcc/testsuite/gnat.dg/addr9_3.adb
new file mode 100644 (file)
index 0000000..f7e3162
--- /dev/null
@@ -0,0 +1,40 @@
+-- { dg-do compile }\r
+\r
+with Ada.Streams; use Ada.Streams;\r
+\r
+procedure Addr9_3 is\r
+\r
+   type Signal_Type is mod 2 ** 16;\r
+\r
+   type A_Item is record\r
+      I : Signal_Type;\r
+      Q : Signal_Type;\r
+   end record\r
+   with Size => 32;\r
+\r
+   for A_Item use record\r
+      I at 0 range 0 .. 15;\r
+      Q at 2 range 0 .. 15;\r
+   end record;\r
+\r
+   type A_Array_Type is\r
+     array (Positive range <>)\r
+     of A_Item\r
+   with Alignment => 16;\r
+\r
+   pragma Pack (A_Array_Type);\r
+\r
+   type B_Array_Type is new Ada.Streams.Stream_Element_Array\r
+   with Alignment => 16;\r
+\r
+   Ct_Count : constant := 7_000;\r
+\r
+   package Set is\r
+      A : aliased A_Array_Type := (1 .. Ct_Count => <>);\r
+      B : B_Array_Type := (1 .. Ct_Count * A_Item'Size / 8 => <>);\r
+      for B'Address use A'Address;\r
+   end Set;\r
+\r
+begin\r
+   null;\r
+end;\r
diff --git a/gcc/testsuite/gnat.dg/addr9_4.adb b/gcc/testsuite/gnat.dg/addr9_4.adb
new file mode 100644 (file)
index 0000000..526d2a0
--- /dev/null
@@ -0,0 +1,40 @@
+-- { dg-do compile }\r
+\r
+with Ada.Streams; use Ada.Streams;\r
+\r
+procedure Addr9_4 is\r
+\r
+   type Signal_Type is mod 2 ** 16;\r
+\r
+   type A_Item is record\r
+      I : Signal_Type;\r
+      Q : Signal_Type;\r
+   end record\r
+   with Size => 32;\r
+\r
+   for A_Item use record\r
+      I at 0 range 0 .. 15;\r
+      Q at 2 range 0 .. 15;\r
+   end record;\r
+\r
+   type A_Array_Type is\r
+     array (Positive range <>)\r
+     of A_Item\r
+   with Alignment => 16;\r
+\r
+   pragma Pack (A_Array_Type);\r
+\r
+   type B_Array_Type is new Ada.Streams.Stream_Element_Array\r
+   with Alignment => 16;\r
+\r
+   Ct_Count : constant := 7_000;\r
+\r
+   package Set is\r
+      A : A_Array_Type := (1 .. Ct_Count => <>);\r
+      B : B_Array_Type := (1 .. Ct_Count * A_Item'Size / 8 => <>);\r
+      for B'Address use A'Address;\r
+   end Set;\r
+\r
+begin\r
+   null;\r
+end;\r