diff options
author | Marc Poulhiès <poulhies@adacore.com> | 2023-09-08 15:15:48 +0000 |
---|---|---|
committer | Marc Poulhiès <poulhies@adacore.com> | 2023-09-19 13:26:42 +0200 |
commit | 047269320d433e4024fcb3580f638bcb2aca7664 (patch) | |
tree | 0734467aac08433e2acd7b56df0b41df00e833ca /gcc/ada/gcc-interface/decl.cc | |
parent | 54c16824f0f05313bfc7df5e625f108b4ff7c636 (diff) | |
download | gcc-047269320d433e4024fcb3580f638bcb2aca7664.zip gcc-047269320d433e4024fcb3580f638bcb2aca7664.tar.gz gcc-047269320d433e4024fcb3580f638bcb2aca7664.tar.bz2 |
ada: Refine upper array bound for bit packed array
When using bit-packed arrays, the compiler creates new array subtypes of
1-bit component indexed by integers. The existing routine checks the
index subtype to find the min/max values. Bit-packed arrays being
indexed by integers, the routines gives up as returning the maximum
possible integer carries no useful information.
This change adds a simple max_value routine that can evaluate very
simple expressions by substituting variables by their min/max value.
Bit-packed array subtypes are currently declared as:
subtype bp_array is packed_bytes1 (0 .. integer((1 * Var + 7) / 8 - 1));
The simple max_value evaluator handles the bare minimum for this
expression pattern.
gcc/ada/ChangeLog:
* gcc-interface/utils.cc (max_value): New.
* gcc-interface/gigi.h (max_value): New.
* gcc-interface/decl.cc (gnat_to_gnu_entity) <E_Array_Subtype>:
When computing gnu_min/gnu_max, try to use max_value if there is
an initial expression.
Diffstat (limited to 'gcc/ada/gcc-interface/decl.cc')
-rw-r--r-- | gcc/ada/gcc-interface/decl.cc | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc index 0cf7d3c..5e16b56 100644 --- a/gcc/ada/gcc-interface/decl.cc +++ b/gcc/ada/gcc-interface/decl.cc @@ -2551,6 +2551,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) else gnu_min = gnu_orig_min; + if (DECL_P (gnu_min) + && DECL_INITIAL (gnu_min) != NULL_TREE + && (TREE_CODE (gnu_min) != INTEGER_CST + || TREE_OVERFLOW (gnu_min))) + { + tree tmp = max_value (DECL_INITIAL(gnu_min), false); + if (TREE_CODE (tmp) == INTEGER_CST + && !TREE_OVERFLOW (tmp)) + gnu_min = tmp; + } + if (TREE_CODE (gnu_min) != INTEGER_CST || TREE_OVERFLOW (gnu_min)) gnu_min = TYPE_MIN_VALUE (TREE_TYPE (gnu_min)); @@ -2560,6 +2571,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition) else gnu_max = gnu_orig_max; + if (DECL_P (gnu_max) + && DECL_INITIAL (gnu_max) != NULL_TREE + && (TREE_CODE (gnu_max) != INTEGER_CST + || TREE_OVERFLOW (gnu_max))) + { + tree tmp = max_value (DECL_INITIAL(gnu_max), true); + if (TREE_CODE (tmp) == INTEGER_CST + && !TREE_OVERFLOW (tmp)) + gnu_max = tmp; + } + if (TREE_CODE (gnu_max) != INTEGER_CST || TREE_OVERFLOW (gnu_max)) gnu_max = TYPE_MAX_VALUE (TREE_TYPE (gnu_max)); |