exp_util.adb (Must_Be_Aligned): Return false for a component of a record that has...
authorEd Schonberg <schonber@gnat.com>
Wed, 5 Dec 2001 00:56:39 +0000 (00:56 +0000)
committerGeert Bosch <bosch@gcc.gnu.org>
Wed, 5 Dec 2001 00:56:39 +0000 (01:56 +0100)
* exp_util.adb (Must_Be_Aligned): Return false for a component of a
record that has other packed components.

From-SVN: r47638

gcc/ada/ChangeLog
gcc/ada/exp_util.adb

index 533df40c5ee414f65478d29b3663dc21b15ff88e..0f72ac5f331f3e35f9e1b3b0c6431a019da4c84a 100644 (file)
@@ -1,3 +1,8 @@
+2001-12-04  Ed Schonberg <schonber@gnat.com>
+
+       * exp_util.adb (Must_Be_Aligned): Return false for a component of a 
+       record that has other packed components.
+
 2001-12-04  Douglass B. Rupp <rupp@gnat.com>
 
        * adaint.c: Minor cleanups.
index 52c1998915089d81f7c0dbc8564bdabf3f8ec7ec..4cdd988aeebf363036b06f94b5bdbab330bc1b80 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---                            $Revision: 1.2 $
+--                            $Revision$
 --                                                                          --
 --          Copyright (C) 1992-2001, Free Software Foundation, Inc.         --
 --                                                                          --
@@ -2497,6 +2497,30 @@ package body Exp_Util is
    function Must_Be_Aligned (Obj : Node_Id) return Boolean is
       Typ : constant Entity_Id := Etype (Obj);
 
+      function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean;
+      --  If the component is in a record that contains previous packed
+      --  components, consider it unaligned because the back-end might
+      --  choose to pack the rest of the record. Lead to less efficient code,
+      --  but safer vis-a-vis of back-end choices.
+
+      function In_Partially_Packed_Record (Comp : Entity_Id) return Boolean is
+         Rec_Type : constant Entity_Id := Scope (Comp);
+         Prev_Comp : Entity_Id;
+      begin
+         Prev_Comp := First_Entity (Rec_Type);
+         while Present (Prev_Comp) loop
+            if Is_Packed (Etype (Prev_Comp)) then
+               return True;
+
+            elsif Prev_Comp = Comp then
+               return False;
+            end if;
+
+            Next_Entity (Prev_Comp);
+         end loop;
+
+         return False;
+      end  In_Partially_Packed_Record;
    begin
       --  If object is strictly aligned, we can quit now
 
@@ -2537,6 +2561,9 @@ package body Exp_Util is
          elsif Present (Component_Clause (Entity (Selector_Name (Obj)))) then
             return False;
 
+         elsif In_Partially_Packed_Record (Entity (Selector_Name (Obj))) then
+            return False;
+
          --  In all other cases, go look at prefix
 
          else