OSDN Git Service

* gcc-interface/decl.c (gnat_to_gnu_entity): Use boolean_type_node in
[pf3gnuchains/gcc-fork.git] / gcc / ada / gcc-interface / decl.c
index 6c97c7d..4c8b66b 100644 (file)
@@ -1931,25 +1931,22 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
 
            /* 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.  */
@@ -2202,16 +2199,40 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
              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