For composite types, any object size should be allowed that is a multiple
of the alignment, but the front end was rejecting some cases. The following
should compile clean, giving the output shown for -gnatR2:

     1. package ObjSizeTest is
     2.    type R is record
     3.       A : Integer;
     4.       B : Character;
     5.    end record;
     6.    for R'Object_Size use 40;
     7.    for R'Size use 40;
     8.    for R'Alignment use 1;
     9. end ObjSizeTest;

Representation information for unit Objsizetest (spec)

for R'Size use 40;
for R'Alignment use 1;
for R use record
   A at 0 range  0 .. 31;
   B at 4 range  0 ..  7;
end record;

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

2014-02-20  Robert Dewar  <de...@adacore.com>

        * sem_ch13.adb (Analyze_Attribute_Definition_Clause, case
        Object_Size): For non-scalar types allow any value that is a
        multiple of 8.
        * gnat_rm.texi: Document Object_Size for composites more clearly.

Index: gnat_rm.texi
===================================================================
--- gnat_rm.texi        (revision 207947)
+++ gnat_rm.texi        (working copy)
@@ -8740,6 +8740,10 @@
 integer field, and so the default size of record objects for this type
 will be 64 (8 bytes).
 
+If the alignment of the above record is specified to be 1, then the
+object size will be 40 (5 bytes). This is true by default, and also
+an object size of 40 can be explicitly specified in this case.
+
 A consequence of this capability is that different object sizes can be
 given to subtypes that would otherwise be considered in Ada to be
 statically matching.  But it makes no sense to consider such subtypes
Index: sem_ch13.adb
===================================================================
--- sem_ch13.adb        (revision 207948)
+++ sem_ch13.adb        (working copy)
@@ -4413,17 +4413,17 @@
             else
                Check_Size (Expr, U_Ent, Size, Biased);
 
-               if Size /= 8
-                    and then
-                  Size /= 16
-                    and then
-                  Size /= 32
-                    and then
-                  UI_Mod (Size, 64) /= 0
-               then
-                  Error_Msg_N
-                    ("Object_Size must be 8, 16, 32, or multiple of 64",
-                     Expr);
+               if Is_Scalar_Type (U_Ent) then
+                  if Size /= 8 and then Size /= 16 and then Size /= 32
+                    and then UI_Mod (Size, 64) /= 0
+                  then
+                     Error_Msg_N
+                       ("Object_Size must be 8, 16, 32, or multiple of 64",
+                        Expr);
+                  end if;
+
+               elsif Size mod 8 /= 0 then
+                  Error_Msg_N ("Object_Size must be a multiple of 8", Expr);
                end if;
 
                Set_Esize (U_Ent, Size);

Reply via email to