This makes the compiler generate an error message also in the case where one
of the specified components overlaps the parent field because its size has
been explicitly set by a size clause.

The compiler must issue an error on 32-bit platforms for the package:

     1. package P is
     2.
     3.   type Byte is mod 2**8;
     4.   for Byte'Size use 8;
     5.
     6.   type Root is tagged record
     7.     Status : Byte;
     8.   end record;
     9.   for Root use record
    10.     Status at 4 range 0 .. 7;
    11.   end record;
    12.   for Root'Size use 64;
    13.
    14.   type Ext is new Root with record
    15.     Thread_Status : Byte;
    16.   end record;
    17.   for Ext use record
    18.     Thread_Status at 5 range 0 .. 7;
            |
        >>> component overlaps parent field of "Ext"

    19.   end record;
    20.
    21. end P;

 21 lines: 1 error

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

2017-09-06  Eric Botcazou  <ebotca...@adacore.com>

        * sem_ch13.adb (Check_Record_Representation_Clause): Give an
        error as soon as one of the specified components overlaps the
        parent field.

Index: sem_ch13.adb
===================================================================
--- sem_ch13.adb        (revision 251784)
+++ sem_ch13.adb        (working copy)
@@ -9806,12 +9806,12 @@
       --  checking for overlap, since no overlap is possible.
 
       Tagged_Parent : Entity_Id := Empty;
-      --  This is set in the case of a derived tagged type for which we have
-      --  Is_Fully_Repped_Tagged_Type True (indicating that all components are
-      --  positioned by record representation clauses). In this case we must
-      --  check for overlap between components of this tagged type, and the
-      --  components of its parent. Tagged_Parent will point to this parent
-      --  type. For all other cases Tagged_Parent is left set to Empty.
+      --  This is set in the case of an extension for which we have either a
+      --  size clause or Is_Fully_Repped_Tagged_Type True (indicating that all
+      --  components are positioned by record representation clauses) on the
+      --  parent type. In this case we check for overlap between components of
+      --  this tagged type and the parent component. Tagged_Parent will point
+      --  to this parent type. For all other cases, Tagged_Parent is Empty.
 
       Parent_Last_Bit : Uint;
       --  Relevant only if Tagged_Parent is set, Parent_Last_Bit indicates the
@@ -9959,19 +9959,23 @@
 
       if Rectype = Any_Type then
          return;
-      else
-         Rectype := Underlying_Type (Rectype);
       end if;
 
+      Rectype := Underlying_Type (Rectype);
+
       --  See if we have a fully repped derived tagged type
 
       declare
          PS : constant Entity_Id := Parent_Subtype (Rectype);
 
       begin
-         if Present (PS) and then Is_Fully_Repped_Tagged_Type (PS) then
+         if Present (PS) and then Known_Static_RM_Size (PS) then
             Tagged_Parent := PS;
+            Parent_Last_Bit := RM_Size (PS) - 1;
 
+         elsif Present (PS) and then Is_Fully_Repped_Tagged_Type (PS) then
+            Tagged_Parent := PS;
+
             --  Find maximum bit of any component of the parent type
 
             Parent_Last_Bit := UI_From_Int (System_Address_Size - 1);
@@ -10063,7 +10067,7 @@
                  ("bit number out of range of specified size",
                   Last_Bit (CC));
 
-               --  Check for overlap with tag component
+               --  Check for overlap with tag or parent component
 
             else
                if Is_Tagged_Type (Rectype)
@@ -10073,27 +10077,20 @@
                     ("component overlaps tag field of&",
                      Component_Name (CC), Rectype);
                   Overlap_Detected := True;
+
+               elsif Present (Tagged_Parent)
+                 and then Fbit <= Parent_Last_Bit
+               then
+                  Error_Msg_NE
+                    ("component overlaps parent field of&",
+                     Component_Name (CC), Rectype);
+                  Overlap_Detected := True;
                end if;
 
                if Hbit < Lbit then
                   Hbit := Lbit;
                end if;
             end if;
-
-            --  Check parent overlap if component might overlap parent field
-
-            if Present (Tagged_Parent) and then Fbit <= Parent_Last_Bit then
-               Pcomp := First_Component_Or_Discriminant (Tagged_Parent);
-               while Present (Pcomp) loop
-                  if not Is_Tag (Pcomp)
-                    and then Chars (Pcomp) /= Name_uParent
-                  then
-                     Check_Component_Overlap (Comp, Pcomp);
-                  end if;
-
-                  Next_Component_Or_Discriminant (Pcomp);
-               end loop;
-            end if;
          end if;
 
          Next (CC);

Reply via email to