From e1ee5cdcbf209d2f16473a2ff6e91ff774edb3e7 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 18 Dec 1997 15:20:19 -0800 Subject: [PATCH] tree.c (build_range_type): Allow creation of ranges with no maximum. * tree.c (build_range_type): Allow creation of ranges with no maximum. * dbxout.c (dbxout_range_type): Handle missing TYPE_MAX_VALUE. * dwarf2out.c (add_subscript_info): Likewise. * dwarfout.c (subscript_data_attribute, byte_size_attribute): Likewise. * sdbout.c (plain_type_1): Likewise. * stmt.c (pushcase_range, all_cases_count, node_has_high_bound): Likewise. * fold-const.c (int_const_binop, fold_convert, make_range, fold): Likewise. From-SVN: r17142 --- gcc/ChangeLog | 12 ++++++++++++ gcc/dbxout.c | 3 ++- gcc/dwarf2out.c | 10 +++++++++- gcc/dwarfout.c | 11 +++++------ gcc/fold-const.c | 45 +++++++++++++++++++++++++++++++++++---------- gcc/sdbout.c | 1 + gcc/stmt.c | 14 +++++++++++++- gcc/tree.c | 18 ++++++++++++------ 8 files changed, 89 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c2ce0453ca2..c1add15087b8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Fri Dec 19 00:19:42 1997 Richard Henderson + + * tree.c (build_range_type): Allow creation of ranges with no maximum. + * dbxout.c (dbxout_range_type): Handle missing TYPE_MAX_VALUE. + * dwarf2out.c (add_subscript_info): Likewise. + * dwarfout.c (subscript_data_attribute, byte_size_attribute): Likewise. + * sdbout.c (plain_type_1): Likewise. + * stmt.c (pushcase_range, all_cases_count, node_has_high_bound): + Likewise. + * fold-const.c (int_const_binop, fold_convert, make_range, fold): + Likewise. + Thu Dec 18 17:05:10 1997 Kaveh R. Ghazi * mips.c (fatal): Remove declaration. diff --git a/gcc/dbxout.c b/gcc/dbxout.c index 11af421106ef..fcb5d86650ea 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -954,7 +954,8 @@ dbxout_range_type (type) TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))); else fprintf (asmfile, ";0"); - if (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST) + if (TYPE_MAX_VALUE (type) + && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST) fprintf (asmfile, ";%d;", TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))); else diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index d321e9f0f3a2..f41cd5efeb03 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -7195,8 +7195,16 @@ add_subscript_info (type_die, type) type_die); } + /* ??? If upper is NULL, the array has unspecified length, + but it does have a lower bound. This happens with Fortran + dimension arr(N:*) + Since the debugger is definitely going to need to know N + to produce useful results, go ahead and output the lower + bound solo, and hope the debugger can cope. */ + add_bound_info (subrange_die, DW_AT_lower_bound, lower); - add_bound_info (subrange_die, DW_AT_upper_bound, upper); + if (upper) + add_bound_info (subrange_die, DW_AT_upper_bound, upper); } else /* We have an array type with an unspecified length. The DWARF-2 diff --git a/gcc/dwarfout.c b/gcc/dwarfout.c index a72ccac5c812..528886a34f8b 100644 --- a/gcc/dwarfout.c +++ b/gcc/dwarfout.c @@ -2587,9 +2587,8 @@ subscript_data_attribute (type) /* Output the representation format byte for this dimension. */ ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, - FMT_CODE (1, - TREE_CODE (lower) == INTEGER_CST, - TREE_CODE (upper) == INTEGER_CST)); + FMT_CODE (1, TREE_CODE (lower) == INTEGER_CST, + (upper && TREE_CODE (upper) == INTEGER_CST))); /* Output the index type for this dimension. */ @@ -2675,9 +2674,9 @@ byte_size_attribute (tree_node) case ARRAY_TYPE: { /* The lower bound is zero, so the length is the upper bound + 1. */ - register tree upper_bound; - upper_bound = TYPE_MAX_VALUE (TYPE_DOMAIN (tree_node)); - size = (unsigned) TREE_INT_CST_LOW (upper_bound) + 1; + register tree upper; + upper = TYPE_MAX_VALUE (TYPE_DOMAIN (tree_node)); + size = upper ? (unsigned) TREE_INT_CST_LOW (upper) + 1 : -1; break; } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 65a6d85efc05..adcb1877d836 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1215,7 +1215,9 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) } if (TREE_TYPE (arg1) == sizetype && hi == 0 - && low >= 0 && low <= TREE_INT_CST_LOW (TYPE_MAX_VALUE (sizetype)) + && low >= 0 + && (TYPE_MAX_VALUE (sizetype) == NULL + || low <= TREE_INT_CST_LOW (TYPE_MAX_VALUE (sizetype))) && ! overflow && ! TREE_OVERFLOW (arg1) && ! TREE_OVERFLOW (arg2)) t = size_int (low); @@ -1532,25 +1534,34 @@ fold_convert (t, arg1) REAL_VALUE_TYPE l; REAL_VALUE_TYPE u; tree type1 = TREE_TYPE (arg1); + int no_upper_bound; x = TREE_REAL_CST (arg1); l = real_value_from_int_cst (type1, TYPE_MIN_VALUE (type)); - u = real_value_from_int_cst (type1, TYPE_MAX_VALUE (type)); + + no_upper_bound = (TYPE_MAX_VALUE (type) == NULL); + if (!no_upper_bound) + u = real_value_from_int_cst (type1, TYPE_MAX_VALUE (type)); + /* See if X will be in range after truncation towards 0. To compensate for truncation, move the bounds away from 0, but reject if X exactly equals the adjusted bounds. */ #ifdef REAL_ARITHMETIC REAL_ARITHMETIC (l, MINUS_EXPR, l, dconst1); - REAL_ARITHMETIC (u, PLUS_EXPR, u, dconst1); + if (!no_upper_bound) + REAL_ARITHMETIC (u, PLUS_EXPR, u, dconst1); #else l--; - u++; + if (!no_upper_bound) + u++; #endif /* If X is a NaN, use zero instead and show we have an overflow. Otherwise, range check. */ if (REAL_VALUE_ISNAN (x)) overflow = 1, x = dconst0; - else if (! (REAL_VALUES_LESS (l, x) && REAL_VALUES_LESS (x, u))) + else if (! (REAL_VALUES_LESS (l, x) + && !no_upper_bound + && REAL_VALUES_LESS (x, u))) overflow = 1; #ifndef REAL_ARITHMETIC @@ -2922,11 +2933,22 @@ make_range (exp, pin_p, plow, phigh) if (TREE_UNSIGNED (type) && ! TREE_UNSIGNED (TREE_TYPE (exp))) { tree equiv_type = type_for_mode (TYPE_MODE (type), 1); - tree high_positive - = fold (build (RSHIFT_EXPR, type, - convert (type, - TYPE_MAX_VALUE (equiv_type)), - convert (type, integer_one_node))); + tree high_positive; + + /* A range without an upper bound is, naturally, unbounded. + Since convert would have cropped a very large value, use + the max value for the destination type. */ + + high_positive = TYPE_MAX_VALUE (equiv_type); + if (!high_positive) + { + high_positive = TYPE_MAX_VALUE (type); + if (!high_positive) + abort(); + } + high_positive = fold (build (RSHIFT_EXPR, type, + convert (type, high_positive), + convert (type, integer_one_node))); /* If the low bound is specified, "and" the range with the range for which the original unsigned value will be @@ -4914,6 +4936,7 @@ fold (expr) if (operand_equal_p (arg0, arg1, 0)) return arg0; if (INTEGRAL_TYPE_P (type) + && TYPE_MAX_VALUE (type) && operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1)) return omit_one_operand (type, arg1, arg0); goto associate; @@ -5397,6 +5420,8 @@ fold (expr) && ! (TREE_CONSTANT (cval1) && TREE_CONSTANT (cval2)) && TREE_TYPE (cval1) == TREE_TYPE (cval2) && INTEGRAL_TYPE_P (TREE_TYPE (cval1)) + && TYPE_MAX_VALUE (TREE_TYPE (cval1)) + && TYPE_MAX_VALUE (TREE_TYPE (cval2)) && ! operand_equal_p (TYPE_MIN_VALUE (TREE_TYPE (cval1)), TYPE_MAX_VALUE (TREE_TYPE (cval2)), 0)) { diff --git a/gcc/sdbout.c b/gcc/sdbout.c index ef1ff29604de..14c5b40dc329 100644 --- a/gcc/sdbout.c +++ b/gcc/sdbout.c @@ -584,6 +584,7 @@ plain_type_1 (type, level) if (sdb_n_dims < SDB_MAX_DIM) sdb_dims[sdb_n_dims++] = (TYPE_DOMAIN (type) + && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST ? (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) diff --git a/gcc/stmt.c b/gcc/stmt.c index 32867482f219..9779015963bc 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -4624,10 +4624,16 @@ pushcase_range (value1, value2, converter, label, duplicate) /* Fail if the range is empty. Do this before any conversion since we want to allow out-of-range empty ranges. */ - if (tree_int_cst_lt (value2, value1)) + if (value2 && tree_int_cst_lt (value2, value1)) return 4; value1 = (*converter) (nominal_type, value1); + + /* If the max was unbounded, use the max of the nominal_type we are + converting to. Do this after the < check above to suppress false + positives. */ + if (!value2) + value2 = TYPE_MAX_VALUE (nominal_type); value2 = (*converter) (nominal_type, value2); /* Fail if these values are out of range. */ @@ -4955,6 +4961,7 @@ all_cases_count (type, spareness) default: case INTEGER_TYPE: if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST + || TYPE_MAX_VALUE (type) == NULL || TREE_CODE (TYPE_MAX_VALUE (type)) != INTEGER_CST) return -1; else @@ -6194,6 +6201,11 @@ node_has_high_bound (node, index_type) tree high_plus_one; case_node_ptr pnode; + /* If there is no upper bound, obviously no test is needed. */ + + if (TYPE_MAX_VALUE (index_type) == NULL) + return 1; + /* If the upper bound of this node is the highest value in the type of the index expression, we need not test against it. */ diff --git a/gcc/tree.c b/gcc/tree.c index 7b150ebf3885..492b6734961a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4002,19 +4002,25 @@ build_range_type (type, lowval, highval) push_obstacks (TYPE_OBSTACK (itype), TYPE_OBSTACK (itype)); TYPE_MIN_VALUE (itype) = convert (type, lowval); - TYPE_MAX_VALUE (itype) = convert (type, highval); + TYPE_MAX_VALUE (itype) = highval ? convert (type, highval) : NULL; pop_obstacks (); TYPE_PRECISION (itype) = TYPE_PRECISION (type); TYPE_MODE (itype) = TYPE_MODE (type); TYPE_SIZE (itype) = TYPE_SIZE (type); TYPE_ALIGN (itype) = TYPE_ALIGN (type); - if ((TREE_CODE (lowval) == INTEGER_CST) - && (TREE_CODE (highval) == INTEGER_CST)) + if (TREE_CODE (lowval) == INTEGER_CST) { - HOST_WIDE_INT highint = TREE_INT_CST_LOW (highval); - HOST_WIDE_INT lowint = TREE_INT_CST_LOW (lowval); - int maxint = (int) (highint - lowint); + HOST_WIDE_INT lowint, highint; + int maxint; + + lowint = TREE_INT_CST_LOW (lowval); + if (highval && TREE_CODE (highval) == INTEGER_CST) + highint = TREE_INT_CST_LOW (highval); + else + highint = (~(unsigned HOST_WIDE_INT)0) >> 1; + + maxint = (int) (highint - lowint); return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype); } else -- 2.43.5