aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_util.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/exp_util.adb')
-rw-r--r--gcc/ada/exp_util.adb93
1 files changed, 93 insertions, 0 deletions
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 6c3911c..5ad0618 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -898,6 +898,52 @@ package body Exp_Util is
return Build_Task_Image_Function (Loc, Decls, Stats, Res);
end Build_Task_Record_Image;
+ ----------------------------------
+ -- Component_May_Be_Bit_Aligned --
+ ----------------------------------
+
+ function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
+ begin
+ -- If no component clause, then everything is fine, since the
+ -- back end never bit-misaligns by default, even if there is
+ -- a pragma Packed for the record.
+
+ if No (Component_Clause (Comp)) then
+ return False;
+ end if;
+
+ -- It is only array and record types that cause trouble
+
+ if not Is_Record_Type (Etype (Comp))
+ and then not Is_Array_Type (Etype (Comp))
+ then
+ return False;
+
+ -- If we know that we have a small (64 bits or less) record
+ -- or bit-packed array, then everything is fine, since the
+ -- back end can handle these cases correctly.
+
+ elsif Esize (Comp) <= 64
+ and then (Is_Record_Type (Etype (Comp))
+ or else Is_Bit_Packed_Array (Etype (Comp)))
+ then
+ return False;
+
+ -- Otherwise if the component is not byte aligned, we
+ -- know we have the nasty unaligned case.
+
+ elsif Normalized_First_Bit (Comp) /= Uint_0
+ or else Esize (Comp) mod System_Storage_Unit /= Uint_0
+ then
+ return True;
+
+ -- If we are large and byte aligned, then OK at this level
+
+ else
+ return False;
+ end if;
+ end Component_May_Be_Bit_Aligned;
+
-------------------------------
-- Convert_To_Actual_Subtype --
-------------------------------
@@ -3877,6 +3923,53 @@ package body Exp_Util is
and then Esize (Left_Typ) = Esize (Result_Typ);
end Target_Has_Fixed_Ops;
+ ------------------------------------------
+ -- Type_May_Have_Bit_Aligned_Components --
+ ------------------------------------------
+
+ function Type_May_Have_Bit_Aligned_Components
+ (Typ : Entity_Id) return Boolean
+ is
+ begin
+ -- Array type, check component type
+
+ if Is_Array_Type (Typ) then
+ return
+ Type_May_Have_Bit_Aligned_Components (Component_Type (Typ));
+
+ -- Record type, check components
+
+ elsif Is_Record_Type (Typ) then
+ declare
+ E : Entity_Id;
+
+ begin
+ E := First_Entity (Typ);
+ while Present (E) loop
+ if Ekind (E) = E_Component
+ or else Ekind (E) = E_Discriminant
+ then
+ if Component_May_Be_Bit_Aligned (E)
+ or else
+ Type_May_Have_Bit_Aligned_Components (Etype (E))
+ then
+ return True;
+ end if;
+ end if;
+
+ Next_Entity (E);
+ end loop;
+
+ return False;
+ end;
+
+ -- Type other than array or record is always OK
+
+ else
+ return False;
+ end if;
+ end Type_May_Have_Bit_Aligned_Components;
+
----------------------------
-- Wrap_Cleanup_Procedure --
----------------------------