/* We can't use build_component_ref here since the template type
isn't complete yet. */
- gnu_orig_min = build3 (COMPONENT_REF, gnu_index_base_type,
- gnu_template_reference, gnu_lb_field,
- NULL_TREE);
- gnu_orig_max = build3 (COMPONENT_REF, gnu_index_base_type,
- gnu_template_reference, gnu_hb_field,
- NULL_TREE);
- TREE_READONLY (gnu_orig_min) = TREE_READONLY (gnu_orig_max) = 1;
-
- gnu_min = convert (sizetype, gnu_orig_min);
- gnu_max = convert (sizetype, gnu_orig_max);
-
- /* Compute the size of this dimension. See the E_Array_Subtype
- case below for the rationale. */
- gnu_high
- = build3 (COND_EXPR, sizetype,
- build2 (GE_EXPR, boolean_type_node,
- gnu_orig_max, gnu_orig_min),
- gnu_max,
- size_binop (MINUS_EXPR, gnu_min, size_one_node));
+ gnu_low = build3 (COMPONENT_REF, gnu_index_base_type,
+ gnu_template_reference, gnu_low_field,
+ NULL_TREE);
+ gnu_high = build3 (COMPONENT_REF, gnu_index_base_type,
+ gnu_template_reference, gnu_high_field,
+ NULL_TREE);
+ TREE_READONLY (gnu_low) = TREE_READONLY (gnu_high) = 1;
+
+ /* Compute the size of this dimension. */
+ gnu_max
+ = build3 (COND_EXPR, gnu_index_base_type,
+ build2 (GE_EXPR, boolean_type_node, gnu_high, gnu_low),
+ gnu_high,
+ build2 (MINUS_EXPR, gnu_index_base_type,
+ gnu_low, fold_convert (gnu_index_base_type,
+ integer_one_node)));
/* Make a range type with the new range in the Ada base type.
Then make an index type with the size range in sizetype. */
else if (TREE_CODE (gnu_max) == INTEGER_CST
&& TREE_CODE (gnu_min) != INTEGER_CST)
{
- gnu_high = gnu_max;
- gnu_min
- = build_cond_expr (sizetype,
- build_binary_op (GE_EXPR,
- boolean_type_node,
- gnu_orig_max,
- gnu_orig_min),
- gnu_min,
- size_binop (PLUS_EXPR, gnu_max,
- size_one_node));
+ gnu_high = size_binop (MINUS_EXPR, gnu_min, size_one_node);
+ gnu_low = size_binop (PLUS_EXPR, gnu_max, size_one_node);
+
+ /* If gnu_high is a constant that has overflowed, the low
+ bound is the smallest integer so cannot be the maximum.
+ If gnu_low is a constant that has overflowed, the high
+ bound is the highest integer so cannot be the minimum. */
+ if ((TREE_CODE (gnu_high) == INTEGER_CST
+ && TREE_OVERFLOW (gnu_high))
+ || (TREE_CODE (gnu_low) == INTEGER_CST
+ && TREE_OVERFLOW (gnu_low)))
+ gnu_high = gnu_max;
+
+ /* If the index type is a subrange and gnu_high a constant
+ that hasn't overflowed, we can use the maximum. */
+ else if (subrange_p && TREE_CODE (gnu_high) == INTEGER_CST)
+ gnu_high = size_binop (MAX_EXPR, gnu_max, gnu_high);
+
+ /* If the index type is a subrange and gnu_low a constant
+ that hasn't overflowed, we can use the minimum. */
+ else if (subrange_p && TREE_CODE (gnu_low) == INTEGER_CST)
+ {
+ gnu_high = gnu_max;
+ gnu_min = size_binop (MIN_EXPR, gnu_min, gnu_low);
+ }
+
+ else
+ gnu_high
+ = build_cond_expr (sizetype,
+ build_binary_op (GE_EXPR,
+ boolean_type_node,
+ gnu_orig_max,
+ gnu_orig_min),
+ gnu_max, gnu_high);
}
/* Finally we use (hb >= lb) ? hb : lb - 1 for the upper bound