diff options
author | Hristian Kirtchev <kirtchev@adacore.com> | 2018-05-23 10:21:42 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2018-05-23 10:21:42 +0000 |
commit | 40016fa77fa2d0e814f9cd851c8863628c677c52 (patch) | |
tree | 8571747bcd27a480cae762f32d87764fb32c348e /gcc/ada/exp_ch4.adb | |
parent | 3d581777692c6e9a03c380daf2c86a64f226850d (diff) | |
download | gcc-40016fa77fa2d0e814f9cd851c8863628c677c52.zip gcc-40016fa77fa2d0e814f9cd851c8863628c677c52.tar.gz gcc-40016fa77fa2d0e814f9cd851c8863628c677c52.tar.bz2 |
[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
Diffstat (limited to 'gcc/ada/exp_ch4.adb')
-rw-r--r-- | gcc/ada/exp_ch4.adb | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 87a0082..3378580 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -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) |