aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/freeze.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/freeze.adb')
-rw-r--r--gcc/ada/freeze.adb373
1 files changed, 191 insertions, 182 deletions
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index de5f8f7..36cf63c 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -937,8 +937,9 @@ package body Freeze is
-- size of packed records if we can tell the size of the packed
-- record in the front end. Packed_Size_Known is True if so far
-- we can figure out the size. It is initialized to True for a
- -- packed record, unless the record has discriminants or atomic
- -- components or independent components.
+ -- packed record, unless the record has either discriminants or
+ -- independent components, or is a strict-alignment type, since
+ -- it cannot be fully packed in this case.
-- The reason we eliminate the discriminated case is that
-- we don't know the way the back end lays out discriminated
@@ -948,8 +949,8 @@ package body Freeze is
Packed_Size_Known : Boolean :=
Is_Packed (T)
and then not Has_Discriminants (T)
- and then not Has_Atomic_Components (T)
- and then not Has_Independent_Components (T);
+ and then not Has_Independent_Components (T)
+ and then not Strict_Alignment (T);
Packed_Size : Uint := Uint_0;
-- Size in bits so far
@@ -997,17 +998,13 @@ package body Freeze is
Packed_Size_Known := False;
end if;
- -- We do not know the packed size for an atomic/VFA type
- -- or component, or an independent type or component, or a
- -- by-reference type or aliased component (because packing
- -- does not touch these).
+ -- We do not know the packed size for an independent
+ -- component or if it is of a strict-alignment type,
+ -- since packing does not touch these (RM 13.2(7)).
- if Is_Atomic_Or_VFA (Ctyp)
- or else Is_Atomic_Or_VFA (Comp)
+ if Is_Independent (Comp)
or else Is_Independent (Ctyp)
- or else Is_Independent (Comp)
- or else Is_By_Reference_Type (Ctyp)
- or else Is_Aliased (Comp)
+ or else Strict_Alignment (Ctyp)
then
Packed_Size_Known := False;
end if;
@@ -1613,23 +1610,33 @@ package body Freeze is
Comp : Entity_Id;
begin
- if Is_Tagged_Type (E) or else Is_Concurrent_Type (E) then
+ if Is_By_Reference_Type (E) then
Set_Strict_Alignment (E);
elsif Is_Array_Type (E) then
- Set_Strict_Alignment (E, Strict_Alignment (Component_Type (E)));
+ if Has_Aliased_Components (E)
+ or else Strict_Alignment (Component_Type (E))
+ then
+ Set_Strict_Alignment (E);
+ end if;
elsif Is_Record_Type (E) then
- if Is_Limited_Record (E) then
- Set_Strict_Alignment (E);
+ -- ??? If the type has convention C_Pass_By_Copy, we consider
+ -- that it may be packed even if it contains aliased parts.
+ -- Such types are very unlikely to be misaligned in practice
+ -- and this makes the compiler accept dubious representation
+ -- clauses used in Florist on types containing arrays with
+ -- aliased components.
+
+ if C_Pass_By_Copy (E) then
return;
end if;
Comp := First_Component (E);
while Present (Comp) loop
if not Is_Type (Comp)
- and then (Strict_Alignment (Etype (Comp))
- or else Is_Aliased (Comp))
+ and then (Is_Aliased (Comp)
+ or else Strict_Alignment (Etype (Comp)))
then
Set_Strict_Alignment (E);
return;
@@ -2622,6 +2629,152 @@ package body Freeze is
end;
end if;
+ -- Check for Aliased or Atomic_Components/Atomic/VFA with
+ -- unsuitable packing or explicit component size clause given.
+
+ if (Has_Aliased_Components (Arr)
+ or else Has_Atomic_Components (Arr)
+ or else Is_Atomic_Or_VFA (Ctyp))
+ and then
+ (Has_Component_Size_Clause (Arr) or else Is_Packed (Arr))
+ then
+ Alias_Atomic_Check : declare
+
+ procedure Complain_CS (T : String);
+ -- Outputs error messages for incorrect CS clause or pragma
+ -- Pack for aliased or atomic/VFA components (T is "aliased"
+ -- or "atomic/vfa");
+
+ -----------------
+ -- Complain_CS --
+ -----------------
+
+ procedure Complain_CS (T : String) is
+ begin
+ if Has_Component_Size_Clause (Arr) then
+ Clause :=
+ Get_Attribute_Definition_Clause
+ (FS, Attribute_Component_Size);
+
+ Error_Msg_N
+ ("incorrect component size for "
+ & T & " components", Clause);
+ Error_Msg_Uint_1 := Esize (Ctyp);
+ Error_Msg_N
+ ("\only allowed value is^", Clause);
+
+ else
+ Error_Msg_N
+ ("?cannot pack " & T & " components (RM 13.2(7))",
+ Get_Rep_Pragma (FS, Name_Pack));
+ Set_Is_Packed (Arr, False);
+ end if;
+ end Complain_CS;
+
+ -- Start of processing for Alias_Atomic_Check
+
+ begin
+ -- If object size of component type isn't known, we cannot
+ -- be sure so we defer to the back end.
+
+ if not Known_Static_Esize (Ctyp) then
+ null;
+
+ -- Case where component size has no effect. First check for
+ -- object size of component type multiple of the storage
+ -- unit size.
+
+ elsif Esize (Ctyp) mod System_Storage_Unit = 0
+
+ -- OK in both packing case and component size case if RM
+ -- size is known and static and same as the object size.
+
+ and then
+ ((Known_Static_RM_Size (Ctyp)
+ and then Esize (Ctyp) = RM_Size (Ctyp))
+
+ -- Or if we have an explicit component size clause and
+ -- the component size and object size are equal.
+
+ or else
+ (Has_Component_Size_Clause (Arr)
+ and then Component_Size (Arr) = Esize (Ctyp)))
+ then
+ null;
+
+ elsif Has_Aliased_Components (Arr) then
+ Complain_CS ("aliased");
+
+ elsif Has_Atomic_Components (Arr)
+ or else Is_Atomic (Ctyp)
+ then
+ Complain_CS ("atomic");
+
+ elsif Is_Volatile_Full_Access (Ctyp) then
+ Complain_CS ("volatile full access");
+ end if;
+ end Alias_Atomic_Check;
+ end if;
+
+ -- Check for Independent_Components/Independent with unsuitable
+ -- packing or explicit component size clause given.
+
+ if (Has_Independent_Components (Arr) or else Is_Independent (Ctyp))
+ and then
+ (Has_Component_Size_Clause (Arr) or else Is_Packed (Arr))
+ then
+ begin
+ -- If object size of component type isn't known, we cannot
+ -- be sure so we defer to the back end.
+
+ if not Known_Static_Esize (Ctyp) then
+ null;
+
+ -- Case where component size has no effect. First check for
+ -- object size of component type multiple of the storage
+ -- unit size.
+
+ elsif Esize (Ctyp) mod System_Storage_Unit = 0
+
+ -- OK in both packing case and component size case if RM
+ -- size is known and multiple of the storage unit size.
+
+ and then
+ ((Known_Static_RM_Size (Ctyp)
+ and then RM_Size (Ctyp) mod System_Storage_Unit = 0)
+
+ -- Or if we have an explicit component size clause and
+ -- the component size is larger than the object size.
+
+ or else
+ (Has_Component_Size_Clause (Arr)
+ and then Component_Size (Arr) >= Esize (Ctyp)))
+ then
+ null;
+
+ else
+ if Has_Component_Size_Clause (Arr) then
+ Clause :=
+ Get_Attribute_Definition_Clause
+ (FS, Attribute_Component_Size);
+
+ Error_Msg_N
+ ("incorrect component size for "
+ & "independent components", Clause);
+ Error_Msg_Uint_1 := Esize (Ctyp);
+ Error_Msg_N
+ ("\minimum allowed is^", Clause);
+
+ else
+ Error_Msg_N
+ ("?cannot pack independent components (RM 13.2(7))",
+ Get_Rep_Pragma (FS, Name_Pack));
+ Set_Is_Packed (Arr, False);
+ end if;
+ end if;
+ end;
+ end if;
+
-- If packing was requested or if the component size was
-- set explicitly, then see if bit packing is required. This
-- processing is only done for base types, since all of the
@@ -2637,7 +2790,7 @@ package body Freeze is
Esiz : Uint;
begin
- if (Is_Packed (Arr) or else Has_Pragma_Pack (Arr))
+ if Is_Packed (Arr)
and then Known_Static_RM_Size (Ctyp)
and then not Has_Component_Size_Clause (Arr)
then
@@ -2797,150 +2950,6 @@ package body Freeze is
end if;
end;
- -- Check for Aliased or Atomic_Components/Atomic/VFA with
- -- unsuitable packing or explicit component size clause given.
-
- if (Has_Aliased_Components (Arr)
- or else Has_Atomic_Components (Arr)
- or else Is_Atomic_Or_VFA (Ctyp))
- and then
- (Has_Component_Size_Clause (Arr) or else Is_Packed (Arr))
- then
- Alias_Atomic_Check : declare
-
- procedure Complain_CS (T : String);
- -- Outputs error messages for incorrect CS clause or pragma
- -- Pack for aliased or atomic/VFA components (T is "aliased"
- -- or "atomic/vfa");
-
- -----------------
- -- Complain_CS --
- -----------------
-
- procedure Complain_CS (T : String) is
- begin
- if Has_Component_Size_Clause (Arr) then
- Clause :=
- Get_Attribute_Definition_Clause
- (FS, Attribute_Component_Size);
-
- Error_Msg_N
- ("incorrect component size for "
- & T & " components", Clause);
- Error_Msg_Uint_1 := Esize (Ctyp);
- Error_Msg_N
- ("\only allowed value is^", Clause);
-
- else
- Error_Msg_N
- ("cannot pack " & T & " components",
- Get_Rep_Pragma (FS, Name_Pack));
- end if;
- end Complain_CS;
-
- -- Start of processing for Alias_Atomic_Check
-
- begin
- -- If object size of component type isn't known, we cannot
- -- be sure so we defer to the back end.
-
- if not Known_Static_Esize (Ctyp) then
- null;
-
- -- Case where component size has no effect. First check for
- -- object size of component type multiple of the storage
- -- unit size.
-
- elsif Esize (Ctyp) mod System_Storage_Unit = 0
-
- -- OK in both packing case and component size case if RM
- -- size is known and static and same as the object size.
-
- and then
- ((Known_Static_RM_Size (Ctyp)
- and then Esize (Ctyp) = RM_Size (Ctyp))
-
- -- Or if we have an explicit component size clause and
- -- the component size and object size are equal.
-
- or else
- (Has_Component_Size_Clause (Arr)
- and then Component_Size (Arr) = Esize (Ctyp)))
- then
- null;
-
- elsif Has_Aliased_Components (Arr) then
- Complain_CS ("aliased");
-
- elsif Has_Atomic_Components (Arr)
- or else Is_Atomic (Ctyp)
- then
- Complain_CS ("atomic");
-
- elsif Is_Volatile_Full_Access (Ctyp) then
- Complain_CS ("volatile full access");
- end if;
- end Alias_Atomic_Check;
- end if;
-
- -- Check for Independent_Components/Independent with unsuitable
- -- packing or explicit component size clause given.
-
- if (Has_Independent_Components (Arr) or else Is_Independent (Ctyp))
- and then
- (Has_Component_Size_Clause (Arr) or else Is_Packed (Arr))
- then
- begin
- -- If object size of component type isn't known, we cannot
- -- be sure so we defer to the back end.
-
- if not Known_Static_Esize (Ctyp) then
- null;
-
- -- Case where component size has no effect. First check for
- -- object size of component type multiple of the storage
- -- unit size.
-
- elsif Esize (Ctyp) mod System_Storage_Unit = 0
-
- -- OK in both packing case and component size case if RM
- -- size is known and multiple of the storage unit size.
-
- and then
- ((Known_Static_RM_Size (Ctyp)
- and then RM_Size (Ctyp) mod System_Storage_Unit = 0)
-
- -- Or if we have an explicit component size clause and
- -- the component size is larger than the object size.
-
- or else
- (Has_Component_Size_Clause (Arr)
- and then Component_Size (Arr) >= Esize (Ctyp)))
- then
- null;
-
- else
- if Has_Component_Size_Clause (Arr) then
- Clause :=
- Get_Attribute_Definition_Clause
- (FS, Attribute_Component_Size);
-
- Error_Msg_N
- ("incorrect component size for "
- & "independent components", Clause);
- Error_Msg_Uint_1 := Esize (Ctyp);
- Error_Msg_N
- ("\minimum allowed is^", Clause);
-
- else
- Error_Msg_N
- ("cannot pack independent components",
- Get_Rep_Pragma (FS, Name_Pack));
- end if;
- end if;
- end;
- end if;
-
-- Warn for case of atomic type
Clause := Get_Rep_Pragma (FS, Name_Atomic);
@@ -4589,18 +4598,6 @@ package body Freeze is
end if;
end if;
- -- Complete error checking on record representation clause (e.g.
- -- overlap of components). This is called after adjusting the
- -- record for reverse bit order.
-
- declare
- RRC : constant Node_Id := Get_Record_Representation_Clause (Rec);
- begin
- if Present (RRC) then
- Check_Record_Representation_Clause (RRC);
- end if;
- end;
-
-- Check for useless pragma Pack when all components placed. We only
-- do this check for record types, not subtypes, since a subtype may
-- have all its components placed, and it still makes perfectly good
@@ -6792,17 +6789,29 @@ package body Freeze is
end if;
end if;
- -- Now that all types from which E may depend are frozen, see if the
- -- size is known at compile time, if it must be unsigned, or if
- -- strict alignment is required
-
- Check_Compile_Time_Size (E);
- Check_Unsigned_Type (E);
+ -- Now that all types from which E may depend are frozen, see if
+ -- strict alignment is required, a component clause on a record
+ -- is correct, the size is known at compile time and if it must
+ -- be unsigned, in that order.
if Base_Type (E) = E then
Check_Strict_Alignment (E);
end if;
+ if Ekind_In (E, E_Record_Type, E_Record_Subtype) then
+ declare
+ RC : constant Node_Id := Get_Record_Representation_Clause (E);
+ begin
+ if Present (RC) then
+ Check_Record_Representation_Clause (RC);
+ end if;
+ end;
+ end if;
+
+ Check_Compile_Time_Size (E);
+
+ Check_Unsigned_Type (E);
+
-- Do not allow a size clause for a type which does not have a size
-- that is known at compile time