summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1997-12-18 23:20:19 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1997-12-18 23:20:19 +0000
commitf52483b521c7b159573fadd04a86feb13363dbc2 (patch)
treef6256a46a8fe9fd54c5f8fa94aaed268e376f33b
parent0ecd40382be58ef287e29464a46f1a173fb5d00c (diff)
downloadgcc-f52483b521c7b159573fadd04a86feb13363dbc2.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@17142 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/dbxout.c3
-rw-r--r--gcc/dwarf2out.c10
-rw-r--r--gcc/dwarfout.c11
-rw-r--r--gcc/fold-const.c45
-rw-r--r--gcc/sdbout.c1
-rw-r--r--gcc/stmt.c14
-rw-r--r--gcc/tree.c18
8 files changed, 89 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8c2ce0453ca..c1add15087b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+Fri Dec 19 00:19:42 1997 Richard Henderson <rth@cygnus.com>
+
+ * 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 <ghazi@caip.rutgers.edu>
* mips.c (fatal): Remove declaration.
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 11af421106e..fcb5d86650e 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 d321e9f0f3a..f41cd5efeb0 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 a72ccac5c81..528886a34f8 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 65a6d85efc0..adcb1877d83 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 ef1ff29604d..14c5b40dc32 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 32867482f21..9779015963b 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 7b150ebf388..492b6734961 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