From: Eric Botcazou <[email protected]>

The RM 13.1(7/5) subclause contains the following sentences: "If the size
of an object is greater than that of its subtype, the additional bits are
padding bits. For an elementary object, these padding bits are normally
read and updated along with the others."

GNAT implements it only for objects of integer and fixed-point types.
For objects of floating-point types, the padding bits are ignored (and
therefore not initialized) with a warning:

  warning: 32 bits of "F" unused [enabled by default]

Implementing it for objects of floating-point types does not seem worth the
hassle, so rejecting nonconfirming size clauses is probably the cleanest
approach (clauses giving the object a size lower than that of its subtype
are already rejected for objects of floating-point types).

gcc/ada/ChangeLog:

        * sem_ch13.adb (Analyze_Attribute_Definition_Clause)
        <Attribute_Size>: Tweak wording of existing error message for the
        size of all elementary objects.  Move error handling for aliased
        objects into the block for objects and give a similar error for
        (nonaliased) floating-point objects.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch13.adb | 47 +++++++++++++++++++++++++++-----------------
 1 file changed, 29 insertions(+), 18 deletions(-)

diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index c2a590dc887..131df3d65d6 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -7834,7 +7834,7 @@ package body Sem_Ch13 is
                         end if;
                      end if;
 
-                  --  For Object'Size, set Esize only
+                  --  For objects, set Esize only
 
                   else
                      if Is_Elementary_Type (Etyp)
@@ -7848,28 +7848,39 @@ package body Sem_Ch13 is
                         Error_Msg_Uint_2 :=
                           UI_From_Int (System_Max_Integer_Size);
                         Error_Msg_N
-                          ("size for primitive object must be a power of 2 in "
-                           & "the range ^-^", N);
+                          ("size for elementary object must be a power of 2 "
+                           & "in the range ^-^", N);
+
+                     --  As per RM 13.1(25/5), only a confirming size clause
+                     --  (i.e. Size = Type'Object_Size) for aliased objects
+                     --  of elementary types is required to be supported.
+                     --  We reject nonconfirming clauses for these objects.
+
+                     elsif Is_Aliased (U_Ent)
+                       and then Is_Elementary_Type (Etyp)
+                       and then Size /= Esize (Etyp)
+                     then
+                        Error_Msg_N
+                          ("nonconfirming Size for aliased object is not "
+                           & "supported", N);
+
+                     --  We also reject nonconfirming clauses for (nonaliased)
+                     --  objects of floating-point types because smaller sizes
+                     --  would require integer operations to access the objects
+                     --  and larger sizes would require integer operations to
+                     --  manipulate the padding bits.
+
+                     elsif Is_Floating_Point_Type (Etyp)
+                       and then Size /= Esize (Etyp)
+                     then
+                        Error_Msg_N
+                          ("nonconfirming Size for floating-point object is "
+                           & "not supported", N);
                      end if;
 
                      Set_Esize (U_Ent, Size);
                   end if;
 
-                  --  As of RM 13.1, only confirming size
-                  --  (i.e. (Size = Esize (Etyp))) for aliased object of
-                  --  elementary type must be supported.
-                  --  GNAT rejects nonconfirming size for such object.
-
-                  if Is_Aliased (U_Ent)
-                    and then Is_Elementary_Type (Etyp)
-                    and then Known_Esize (U_Ent)
-                    and then Size /= Esize (Etyp)
-                  then
-                     Error_Msg_N
-                       ("nonconfirming Size for aliased object is not "
-                        & "supported", N);
-                  end if;
-
                   --  Handle extension aspect 'Size'Class which allows for
                   --  "mutably tagged" types.
 
-- 
2.51.0

Reply via email to