diff options
Diffstat (limited to 'gcc/ada/exp_aggr.adb')
-rw-r--r-- | gcc/ada/exp_aggr.adb | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb index 8aca0d2..92c040e 100644 --- a/gcc/ada/exp_aggr.adb +++ b/gcc/ada/exp_aggr.adb @@ -4895,14 +4895,14 @@ package body Exp_Aggr is -- 1. N consists of a single OTHERS choice, possibly recursively - -- 2. The array type is not packed + -- 2. The array type has no null ranges (the purpose of this is to + -- avoid a bogus warning for an out-of-range value). -- 3. The array type has no atomic components - -- 4. The array type has no null ranges (the purpose of this is to - -- avoid a bogus warning for an out-of-range value). + -- 4. The component type is elementary - -- 5. The component type is elementary + -- 5. The component size is a multiple of Storage_Unit -- 6. The component size is Storage_Unit or the value is of the form -- M * (1 + A**1 + A**2 + .. A**(K-1)) where A = 2**(Storage_Unit) @@ -4918,6 +4918,7 @@ package body Exp_Aggr is Expr : Node_Id := N; Low : Node_Id; High : Node_Id; + Csiz : Uint; Remainder : Uint; Value : Uint; Nunits : Nat; @@ -4933,14 +4934,6 @@ package body Exp_Aggr is return False; end if; - if Present (Packed_Array_Impl_Type (Ctyp)) then - return False; - end if; - - if Has_Atomic_Components (Ctyp) then - return False; - end if; - Index := First_Index (Ctyp); while Present (Index) loop Get_Index_Bounds (Index, Low, High); @@ -4964,6 +4957,11 @@ package body Exp_Aggr is Expr := Expression (First (Component_Associations (Expr))); end loop; + if Has_Atomic_Components (Ctyp) then + return False; + end if; + + Csiz := Component_Size (Ctyp); Ctyp := Component_Type (Ctyp); if Is_Atomic_Or_VFA (Ctyp) then @@ -4978,20 +4976,19 @@ package body Exp_Aggr is return False; end if; - -- All elementary types are supported + -- Access types need to be dealt with specially - if not Is_Elementary_Type (Ctyp) then - return False; - end if; + if Is_Access_Type (Ctyp) then - -- However access types need to be dealt with specially + -- Component_Size is not set by Layout_Type if the component + -- type is an access type ??? - if Is_Access_Type (Ctyp) then + Csiz := Esize (Ctyp); -- Fat pointers are rejected as they are not really elementary -- for the backend. - if Esize (Ctyp) /= System_Address_Size then + if Csiz /= System_Address_Size then return False; end if; @@ -5002,15 +4999,26 @@ package body Exp_Aggr is if Nkind (Expr) /= N_Null and then not Is_Entity_Name (Expr) then return False; end if; + + -- Scalar types are OK if their size is a multiple of Storage_Unit + + elsif Is_Scalar_Type (Ctyp) then + + if Csiz mod System_Storage_Unit /= 0 then + return False; + end if; + + -- Composite types are rejected + + else + return False; end if; -- The expression needs to be analyzed if True is returned Analyze_And_Resolve (Expr, Ctyp); - -- The back end uses the Esize as the precision of the type - - Nunits := UI_To_Int (Esize (Ctyp)) / System_Storage_Unit; + Nunits := UI_To_Int (Csiz) / System_Storage_Unit; if Nunits = 1 then return True; |