This plugs a loophole in the validation of component size aspects/clauses
specified for array types, by copying what is done for record types.
Tested on x86-64/Linux, applied on the mainline.
2026-02-08 Eric Botcazou <[email protected]>
Liam Powell <[email protected]>
PR ada/121576
* freeze.adb (Freeze_Array_Type): When the component size is
specified, check that it is valid when the component type is
either a fixed-point type or a bit-packed array type.
2026-02-08 Eric Botcazou <[email protected]>
Liam Powell <[email protected]>
* gnat.dg/specs/component_size1.ads: New test.
--
Eric Botcazoudiff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index c1c6bac1fd6..836d84f6534 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -3645,6 +3645,9 @@ package body Freeze is
Clause : Node_Id;
-- Set to Component_Size clause or Atomic pragma, if any
+ Junk : Boolean;
+ pragma Warnings (Off, Junk);
+
Non_Standard_Enum : Boolean := False;
-- Set true if any of the index types is an enumeration type with a
-- non-standard representation.
@@ -3793,6 +3796,21 @@ package body Freeze is
then
Complain_CS ("independent", Min => True);
end if;
+
+ -- If the component is of a fixed-point type, we must check
+ -- the size. This is not done until the freeze point since,
+ -- for fixed-point types, we do not know the size until the
+ -- type is frozen. Likewise for a bit-packed array type.
+
+ if Is_Fixed_Point_Type (Ctyp)
+ or else Is_Bit_Packed_Array (Ctyp)
+ then
+ Clause :=
+ Get_Attribute_Definition_Clause
+ (FS, Attribute_Component_Size);
+ Check_Size
+ (Expression (Clause), Ctyp, Component_Size (Arr), Junk);
+ end if;
end CS_Check;
-- Check for Aliased or Atomic or Full Access or Independent
-- { dg-do compile }
-- { dg-options "-gnatc" }
package Component_Size1 is
type T1 is delta 2.0**(-8) range 0.0 .. 1.0 - 2.0**(-8);
type Arr1 is array (Boolean) of T1
with Component_Size => 1; -- { dg-error "too small" }
type Rec1 is record
Comp : T1;
end record;
for Rec1 use record
Comp at 0 range 0 .. 0; -- { dg-error "too small" }
end record;
type T2 is array (1 .. 8) of Boolean with Pack => True;
type Arr2 is array (Boolean) of T2
with Component_Size => 1; -- { dg-error "too small" }
type Rec2 is record
Comp : T2;
end record;
for Rec2 use record
Comp at 0 range 0 .. 0; -- { dg-error "too small" }
end record;
end Component_Size1;