[Ada] Initialize_Scalars optimization causes spurious runtime check failure
This patch suppresses the optimization of scalar arrays when pragma Initialize_Scalars is in effect if the component type is subject to predicates. Since the scalar array is initialized with invalid values, these values may violate the predicate or a validity check within the predicate. ------------ -- Source -- ------------ -- gnat.adc pragma Initialize_Scalars; -- types.ads with System; use System; package Types is type Byte is mod System.Storage_Unit; subtype Inter_Byte is Byte; function Always_OK (B : Inter_Byte) return Boolean is (True); function Is_OK (B : Inter_Byte) return Boolean is (Always_OK (B)); subtype Final_Byte is Byte with Predicate => Is_OK (Final_Byte); type Bytes is array (1 .. 5) of Final_Byte; Obj : Bytes; end Types; -- main.adb with Types; use Types; procedure Main is begin null; end Main; ----------------- -- Compilation -- ----------------- $ gnatmake -q -gnata -gnatVa main.adb $ ./main 2018-05-23 Hristian Kirtchev <kirtchev@adacore.com> gcc/ada/ * exp_ch3.adb (Default_Initialize_Object): Do not optimize scalar array initialization when the component type has predicates. * exp_ch4.adb (Expand_N_Allocator): Do not optimize scalar array allocation when the component type has predicates. From-SVN: r260572
This commit is contained in:
parent
3d58177769
commit
40016fa77f
3 changed files with 64 additions and 29 deletions
|
@ -1,3 +1,10 @@
|
|||
2018-05-23 Hristian Kirtchev <kirtchev@adacore.com>
|
||||
|
||||
* exp_ch3.adb (Default_Initialize_Object): Do not optimize scalar array
|
||||
initialization when the component type has predicates.
|
||||
* exp_ch4.adb (Expand_N_Allocator): Do not optimize scalar array
|
||||
allocation when the component type has predicates.
|
||||
|
||||
2018-05-23 Hristian Kirtchev <kirtchev@adacore.com>
|
||||
|
||||
* einfo.adb, exp_disp.adb, sem_ch3.adb, sem_ch6.adb, sem_prag.adb:
|
||||
|
|
|
@ -6069,29 +6069,43 @@ package body Exp_Ch3 is
|
|||
null;
|
||||
|
||||
-- Optimize the default initialization of an array object when
|
||||
-- the following conditions are met:
|
||||
--
|
||||
-- * Pragma Initialize_Scalars or Normalize_Scalars is in
|
||||
-- effect.
|
||||
--
|
||||
-- * The bounds of the array type are static and lack empty
|
||||
-- ranges.
|
||||
--
|
||||
-- * The array type does not contain atomic components or is
|
||||
-- treated as packed.
|
||||
--
|
||||
-- * The component is of a scalar type which requires simple
|
||||
-- initialization.
|
||||
--
|
||||
-- pragma Initialize_Scalars or Normalize_Scalars is in effect.
|
||||
-- Construct an in-place initialization aggregate which may be
|
||||
-- convert into a fast memset by the backend.
|
||||
|
||||
elsif Init_Or_Norm_Scalars
|
||||
and then Is_Array_Type (Typ)
|
||||
|
||||
-- The array must lack atomic components because they are
|
||||
-- treated as non-static, and as a result the backend will
|
||||
-- not initialize the memory in one go.
|
||||
|
||||
and then not Has_Atomic_Components (Typ)
|
||||
|
||||
-- The array must not be packed because the invalid values
|
||||
-- in System.Scalar_Values are multiples of Storage_Unit.
|
||||
|
||||
and then not Is_Packed (Typ)
|
||||
|
||||
-- The array must have static non-empty ranges, otherwise
|
||||
-- the backend cannot initialize the memory in one go.
|
||||
|
||||
and then Has_Static_Non_Empty_Array_Bounds (Typ)
|
||||
|
||||
-- The optimization is only relevant for arrays of scalar
|
||||
-- types.
|
||||
|
||||
and then Is_Scalar_Type (Component_Type (Typ))
|
||||
|
||||
-- Similar to regular array initialization using a type
|
||||
-- init proc, predicate checks are not performed because the
|
||||
-- initialization values are intentionally invalid, and may
|
||||
-- violate the predicate.
|
||||
|
||||
and then not Has_Predicates (Component_Type (Typ))
|
||||
|
||||
-- The component type must have a single initialization value
|
||||
|
||||
and then Simple_Initialization_OK (Component_Type (Typ))
|
||||
then
|
||||
Set_No_Initialization (N, False);
|
||||
|
|
|
@ -4618,28 +4618,42 @@ package body Exp_Ch4 is
|
|||
Is_Allocate => True);
|
||||
end if;
|
||||
|
||||
-- Optimize the default allocation of an array object when the
|
||||
-- following conditions are met:
|
||||
--
|
||||
-- * Pragma Initialize_Scalars or Normalize_Scalars is in effect
|
||||
--
|
||||
-- * The bounds of the array type are static and lack empty ranges
|
||||
--
|
||||
-- * The array type does not contain atomic components or is
|
||||
-- treated as packed.
|
||||
--
|
||||
-- * The component is of a scalar type which requires simple
|
||||
-- initialization.
|
||||
--
|
||||
-- Construct an in-place initialization aggregate which may be
|
||||
-- convert into a fast memset by the backend.
|
||||
-- Optimize the default allocation of an array object when pragma
|
||||
-- Initialize_Scalars or Normalize_Scalars is in effect. Construct an
|
||||
-- in-place initialization aggregate which may be convert into a fast
|
||||
-- memset by the backend.
|
||||
|
||||
elsif Init_Or_Norm_Scalars
|
||||
and then Is_Array_Type (T)
|
||||
|
||||
-- The array must lack atomic components because they are treated
|
||||
-- as non-static, and as a result the backend will not initialize
|
||||
-- the memory in one go.
|
||||
|
||||
and then not Has_Atomic_Components (T)
|
||||
|
||||
-- The array must not be packed because the invalid values in
|
||||
-- System.Scalar_Values are multiples of Storage_Unit.
|
||||
|
||||
and then not Is_Packed (T)
|
||||
|
||||
-- The array must have static non-empty ranges, otherwise the
|
||||
-- backend cannot initialize the memory in one go.
|
||||
|
||||
and then Has_Static_Non_Empty_Array_Bounds (T)
|
||||
|
||||
-- The optimization is only relevant for arrays of scalar types
|
||||
|
||||
and then Is_Scalar_Type (Component_Type (T))
|
||||
|
||||
-- Similar to regular array initialization using a type init proc,
|
||||
-- predicate checks are not performed because the initialization
|
||||
-- values are intentionally invalid, and may violate the predicate.
|
||||
|
||||
and then not Has_Predicates (Component_Type (T))
|
||||
|
||||
-- The component type must have a single initialization value
|
||||
|
||||
and then Needs_Simple_Initialization
|
||||
(Typ => Component_Type (T),
|
||||
Consider_IS => True)
|
||||
|
|
Loading…
Add table
Reference in a new issue