aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch4.adb
diff options
context:
space:
mode:
authorHristian Kirtchev <kirtchev@adacore.com>2018-05-23 10:21:42 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2018-05-23 10:21:42 +0000
commit40016fa77fa2d0e814f9cd851c8863628c677c52 (patch)
tree8571747bcd27a480cae762f32d87764fb32c348e /gcc/ada/exp_ch4.adb
parent3d581777692c6e9a03c380daf2c86a64f226850d (diff)
downloadgcc-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.adb44
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)