Commit 40016fa7 by Hristian Kirtchev Committed by Pierre-Marie de Rodat

[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
parent 3d581777
2018-05-23 Hristian Kirtchev <kirtchev@adacore.com> 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: * einfo.adb, exp_disp.adb, sem_ch3.adb, sem_ch6.adb, sem_prag.adb:
Minor reformatting. Minor reformatting.
......
...@@ -6069,29 +6069,43 @@ package body Exp_Ch3 is ...@@ -6069,29 +6069,43 @@ package body Exp_Ch3 is
null; null;
-- Optimize the default initialization of an array object when -- Optimize the default initialization of an array object when
-- the following conditions are met: -- pragma Initialize_Scalars or Normalize_Scalars is in effect.
--
-- * 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 -- Construct an in-place initialization aggregate which may be
-- convert into a fast memset by the backend. -- convert into a fast memset by the backend.
elsif Init_Or_Norm_Scalars elsif Init_Or_Norm_Scalars
and then Is_Array_Type (Typ) 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) 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) 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) 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)) 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)) and then Simple_Initialization_OK (Component_Type (Typ))
then then
Set_No_Initialization (N, False); Set_No_Initialization (N, False);
......
...@@ -4618,28 +4618,42 @@ package body Exp_Ch4 is ...@@ -4618,28 +4618,42 @@ package body Exp_Ch4 is
Is_Allocate => True); Is_Allocate => True);
end if; end if;
-- Optimize the default allocation of an array object when the -- Optimize the default allocation of an array object when pragma
-- following conditions are met: -- Initialize_Scalars or Normalize_Scalars is in effect. Construct an
-- -- in-place initialization aggregate which may be convert into a fast
-- * Pragma Initialize_Scalars or Normalize_Scalars is in effect -- memset by the backend.
--
-- * 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.
elsif Init_Or_Norm_Scalars elsif Init_Or_Norm_Scalars
and then Is_Array_Type (T) 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) 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) 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) 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)) 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 and then Needs_Simple_Initialization
(Typ => Component_Type (T), (Typ => Component_Type (T),
Consider_IS => True) Consider_IS => True)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment