Thread View: gnu.gcc.bug
1 messages
1 total messages
Started by Paul Eggert
Thu, 03 Sep 1992 04:12
GCC 2.2.2 patches for overflow detection in constant expressions
Author: Paul Eggert
Date: Thu, 03 Sep 1992 04:12
Date: Thu, 03 Sep 1992 04:12
900 lines
25974 bytes
25974 bytes
GCC 2.2.2 doesn't check for overflow in constant expressions, even though it
really should -- not only because ANSI says so, but because it catches several
all-too-common coding errors. Here is a patch.
Thu Sep 3 02:33:55 1992 Paul Eggert (eggert@twinsun.com)
* c-typeck.c (constant_expression_warning): Now works;
it reports signed integer overflow in constant expressions,
and uncasted negative constants that appear in unsigned contexts.
(build_c_cast, convert_for_assignment, parser_build_binary_op,
store_init_value) Check for overflow.
* c-parse.y (unary_expr): Likewise.
* c-tree.h (constant_expression_warning): Now exported.
* fold-const.c (left_shift_overflows, possible_sum_sign) New macros.
(force_fit_type): Mark overflowed or truncated INTEGER_CSTs.
(add_double, div_and_round_double, lshift_double, mul_double,
neg_double, const_binop, fold): Check for signed integer overflow.
(const_binop, fold_convert): Use pedwarn for overflow warnings.
Say `constant expression', not `constant folding', for user's sake.
===================================================================
RCS file: c-parse.y,v
retrieving revision 2.2.2.3
diff -c2 -r2.2.2.3 c-parse.y
*** c-parse.y 1992/08/13 23:59:47 2.2.2.3
--- c-parse.y 1992/09/02 19:17:38
***************
*** 331,335 ****
pedantic = $<itype>1; }
| unop cast_expr %prec UNARY
! { $$ = build_unary_op ($1, $2, 0); }
/* Refer to the address of a label as a pointer. */
| ANDAND identifier
--- 331,336 ----
pedantic = $<itype>1; }
| unop cast_expr %prec UNARY
! { $$ = build_unary_op ($1, $2, 0);
! constant_expression_warning ($$, 0); }
/* Refer to the address of a label as a pointer. */
| ANDAND identifier
===================================================================
RCS file: c-tree.h,v
retrieving revision 2.2
diff -c2 -r2.2 c-tree.h
*** c-tree.h 1992/03/14 20:55:54 2.2
--- c-tree.h 1992/09/02 19:15:57
***************
*** 108,111 ****
--- 108,112 ----
extern tree c_expand_start_case ();
extern tree default_conversion ();
+ extern void constant_expression_warning ();
/* Given two integer or real types, return the type for their sum.
===================================================================
RCS file: c-typeck.c,v
retrieving revision 2.2.2.7
diff -c2 -r2.2.2.7 c-typeck.c
*** c-typeck.c 1992/08/29 23:55:12 2.2.2.7
--- c-typeck.c 1992/09/03 02:27:45
***************
*** 785,796 ****
/* Print a warning if a constant expression had overflow in folding.
! This doesn't really work--it is waiting for changes in fold. */
void
! constant_expression_warning (value)
tree value;
{
! if (TREE_CODE (value) == NON_LVALUE_EXPR && TREE_CONSTANT_OVERFLOW (value))
! pedwarn ("overflow in constant expression");
}
--- 785,804 ----
/* Print a warning if a constant expression had overflow in folding.
! If EVEN_IF_UNSIGNED is nonzero, warn even if the expression is unsigned. */
void
! constant_expression_warning (value, even_if_unsigned)
tree value;
+ int even_if_unsigned;
{
! if (TREE_CODE (value) == INTEGER_CST
! && TREE_CONSTANT_OVERFLOW (value)
! && (! TREE_UNSIGNED (TREE_TYPE (value)) || even_if_unsigned))
! {
! TREE_CONSTANT_OVERFLOW (value) = 0;
! pedwarn (TREE_UNSIGNED (TREE_TYPE (value))
! ? "constant expression out of range for unsigned type"
! : "signed integer overflow in constant expression");
! }
}
***************
*** 2135,2138 ****
--- 2143,2148 ----
warning ("comparisons like X<=Y<=Z do not have the usual meaning");
+ constant_expression_warning (result, 0);
+
class = TREE_CODE_CLASS (TREE_CODE (result));
***************
*** 3728,3731 ****
--- 3738,3742 ----
value = convert (type, value);
+ constant_expression_warning (value, 0);
}
***************
*** 3946,3950 ****
(coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE))
{
! return convert (type, rhs);
}
/* Conversions among pointers */
--- 3957,3963 ----
(coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE))
{
! tree t = convert (type, rhs);
! constant_expression_warning (t, 1);
! return t;
}
/* Conversions among pointers */
***************
*** 4233,4237 ****
/* ANSI wants warnings about out-of-range constant initializers. */
! constant_expression_warning (value);
DECL_INITIAL (decl) = value;
--- 4246,4250 ----
/* ANSI wants warnings about out-of-range constant initializers. */
! constant_expression_warning (value, 1);
DECL_INITIAL (decl) = value;
===================================================================
RCS file: fold-const.c,v
retrieving revision 2.2.2.4
diff -c2 -r2.2.2.4 fold-const.c
*** fold-const.c 1992/08/29 08:21:30 2.2.2.4
--- fold-const.c 1992/09/03 02:33:55
***************
*** 49,53 ****
static jmp_buf float_error;
! void lshift_double ();
void rshift_double ();
void lrotate_double ();
--- 49,53 ----
static jmp_buf float_error;
! int lshift_double ();
void rshift_double ();
void lrotate_double ();
***************
*** 54,57 ****
--- 54,65 ----
void rrotate_double ();
static tree const_binop ();
+
+ /* Yield nonzero if a signed left shift of A by B bits overflows.
+ A is a C int; B is nonnegative. */
+ #define left_shift_overflows(a, b) ((a) ^ ((a) << (b)) >> (b))
+
+ /* Yield nonzero if adding two numbers with A's and B's signs can yield a
+ number with SUM's sign, where A, B, and SUM are all C ints. */
+ #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
/* To do constant folding on INTEGER_CST nodes requires 64-bit arithmetic.
***************
*** 97,106 ****
/* Make the integer constant T valid for its type
by setting to 0 or 1 all the bits in the constant
! that don't belong in the type. */
static void
! force_fit_type (t)
tree t;
{
register int prec = TYPE_PRECISION (TREE_TYPE (t));
--- 105,119 ----
/* Make the integer constant T valid for its type
by setting to 0 or 1 all the bits in the constant
! that don't belong in the type.
! Mark the constant if it has overflowed.
! If OVERFLOW is nonzero and the result is signed,
! the calculation has already overflowed. */
static void
! force_fit_type (t, overflow)
tree t;
+ int overflow;
{
+ int low = TREE_INT_CST_LOW (t), high = TREE_INT_CST_HIGH (t);
register int prec = TYPE_PRECISION (TREE_TYPE (t));
***************
*** 148,154 ****
--- 161,174 ----
}
}
+
+ /* In C, by definition, unsigned arithmetic does not overflow.
+ But sometimes we want to warn about unsigned truncation. */
+ if ((low ^ TREE_INT_CST_LOW (t)) | (high ^ TREE_INT_CST_HIGH (t))
+ || overflow && ! TREE_UNSIGNED (TREE_TYPE (t)))
+ TREE_CONSTANT_OVERFLOW (t) = 1;
}
/* Add two 64-bit integers with 64-bit result.
+ Yield nonzero if the (signed) operation overflows.
Each argument is given as two `int' pieces.
One argument is L1 and H1; the other, L2 and H2.
***************
*** 156,160 ****
We use the 8-shorts representation internally. */
! void
add_double (l1, h1, l2, h2, lv, hv)
int l1, h1, l2, h2;
--- 176,180 ----
We use the 8-shorts representation internally. */
! int
add_double (l1, h1, l2, h2, lv, hv)
int l1, h1, l2, h2;
***************
*** 177,183 ****
--- 197,205 ----
decode (arg1, lv, hv);
+ return !possible_sum_sign (h1, h2, *hv);
}
/* Negate a 64-bit integers with 64-bit result.
+ Yield nonzero if the (signed) operation overflows.
The argument is given as two `int' pieces in L1 and H1.
The value is stored as two `int' pieces in *LV and *HV.
***************
*** 184,188 ****
We use the 8-shorts representation internally. */
! void
neg_double (l1, h1, lv, hv)
int l1, h1;
--- 206,210 ----
We use the 8-shorts representation internally. */
! int
neg_double (l1, h1, lv, hv)
int l1, h1;
***************
*** 199,205 ****
--- 221,229 ----
*hv = ~ h1;
}
+ return (h1 & *hv) < 0;
}
/* Multiply two 64-bit integers with 64-bit result.
+ Yield nonzero if the (signed) operation overflows.
Each argument is given as two `int' pieces.
One argument is L1 and H1; the other, L2 and H2.
***************
*** 207,211 ****
We use the 8-shorts representation internally. */
! void
mul_double (l1, h1, l2, h2, lv, hv)
int l1, h1, l2, h2;
--- 231,235 ----
We use the 8-shorts representation internally. */
! int
mul_double (l1, h1, l2, h2, lv, hv)
int l1, h1, l2, h2;
***************
*** 217,223 ****
register int carry = 0;
register int i, j, k;
! /* These two cases are used extensively, arising from pointer
! combinations. */
if (h2 == 0)
{
--- 241,247 ----
register int carry = 0;
register int i, j, k;
+ int toplow, tophigh, neglow, neghigh;
! /* These cases are used extensively, arising from pointer combinations. */
if (h2 == 0)
{
***************
*** 224,236 ****
if (l2 == 2)
{
unsigned temp = l1 + l1;
! *hv = h1 * 2 + (temp < l1);
*lv = temp;
! return;
}
if (l2 == 4)
{
unsigned temp = l1 + l1;
! h1 = h1 * 4 + ((temp < l1) << 1);
l1 = temp;
temp += temp;
--- 248,262 ----
if (l2 == 2)
{
+ int overflow = left_shift_overflows (h1, 1);
unsigned temp = l1 + l1;
! *hv = (h1 << 1) + (temp < l1);
*lv = temp;
! return overflow;
}
if (l2 == 4)
{
+ int overflow = left_shift_overflows (h1, 2);
unsigned temp = l1 + l1;
! h1 = (h1 << 2) + ((temp < l1) << 1);
l1 = temp;
temp += temp;
***************
*** 238,247 ****
*lv = temp;
*hv = h1;
! return;
}
if (l2 == 8)
{
unsigned temp = l1 + l1;
! h1 = h1 * 8 + ((temp < l1) << 2);
l1 = temp;
temp += temp;
--- 264,274 ----
*lv = temp;
*hv = h1;
! return overflow;
}
if (l2 == 8)
{
+ int overflow = left_shift_overflows (h1, 3);
unsigned temp = l1 + l1;
! h1 = (h1 << 3) + ((temp < l1) << 2);
l1 = temp;
temp += temp;
***************
*** 252,256 ****
*lv = temp;
*hv = h1;
! return;
}
}
--- 279,283 ----
*lv = temp;
*hv = h1;
! return overflow;
}
}
***************
*** 276,279 ****
--- 303,321 ----
decode (prod, lv, hv); /* @@decode ignores prod[8] -> prod[15] */
+
+ /* Check for overflow by calculating the top half of the answer in full;
+ it should agree with the low half's sign bit. */
+ decode (prod+8, &toplow, &tophigh);
+ if (h1 < 0)
+ {
+ neg_double (l2, h2, &neglow, &neghigh);
+ add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
+ }
+ if (h2 < 0)
+ {
+ neg_double (l1, h1, &neglow, &neghigh);
+ add_double (neglow, neghigh, toplow, tophigh, &toplow, &tophigh);
+ }
+ return *hv < 0 ? ~(toplow & tophigh) : (toplow | tophigh);
}
***************
*** 282,288 ****
Shift right if COUNT is negative.
ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
Store the value as two `int' pieces in *LV and *HV. */
! void
lshift_double (l1, h1, count, prec, lv, hv, arith)
int l1, h1, count, prec;
--- 324,331 ----
Shift right if COUNT is negative.
ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
+ Yield nonzero if the arithmetic shift overflows.
Store the value as two `int' pieces in *LV and *HV. */
! int
lshift_double (l1, h1, count, prec, lv, hv, arith)
int l1, h1, count, prec;
***************
*** 292,296 ****
short arg1[8];
register int i;
! register int carry;
if (count < 0)
--- 335,339 ----
short arg1[8];
register int i;
! register int carry, overflow;
if (count < 0)
***************
*** 297,301 ****
{
rshift_double (l1, h1, - count, prec, lv, hv, arith);
! return;
}
--- 340,344 ----
{
rshift_double (l1, h1, - count, prec, lv, hv, arith);
! return 0;
}
***************
*** 305,308 ****
--- 348,352 ----
count = prec;
+ overflow = 0;
while (count > 0)
{
***************
*** 315,325 ****
}
count--;
}
decode (arg1, lv, hv);
}
/* Shift the 64-bit integer in L1, H1 right by COUNT places
! keeping only PREC bits of result. COUNT must be positive.
ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
Store the value as two `int' pieces in *LV and *HV. */
--- 359,371 ----
}
count--;
+ overflow |= carry ^ (arg1[7] >> 7);
}
decode (arg1, lv, hv);
+ return overflow;
}
/* Shift the 64-bit integer in L1, H1 right by COUNT places
! keeping only PREC bits of result. COUNT must be nonnegative.
ARITH nonzero specifies arithmetic shifting; otherwise use logical shift.
Store the value as two `int' pieces in *LV and *HV. */
***************
*** 434,440 ****
or EXACT_DIV_EXPR
It controls how the quotient is rounded to a integer.
UNS nonzero says do unsigned division. */
! static void
div_and_round_double (code, uns,
lnum_orig, hnum_orig, lden_orig, hden_orig,
--- 480,487 ----
or EXACT_DIV_EXPR
It controls how the quotient is rounded to a integer.
+ Yield nonzero if the operation overflows.
UNS nonzero says do unsigned division. */
! static int
div_and_round_double (code, uns,
lnum_orig, hnum_orig, lden_orig, hden_orig,
***************
*** 454,457 ****
--- 501,505 ----
unsigned int lden = lden_orig;
int hden = hden_orig;
+ int overflow = 0;
if ((hden == 0) && (lden == 0))
***************
*** 461,473 ****
if (!uns)
{
! if (hden < 0)
{
quo_neg = ~ quo_neg;
! neg_double (lden, hden, &lden, &hden);
}
! if (hnum < 0)
{
quo_neg = ~ quo_neg;
! neg_double (lnum, hnum, &lnum, &hnum);
}
}
--- 509,523 ----
if (!uns)
{
! if (hnum < 0)
{
quo_neg = ~ quo_neg;
! /* (minimum integer) / (-1) is the only overflow case. */
! if (neg_double (lnum, hnum, &lnum, &hnum))
! overflow = ~(hden & lden);
}
! if (hden < 0)
{
quo_neg = ~ quo_neg;
! neg_double (lden, hden, &lden, &hden);
}
}
***************
*** 642,646 ****
case TRUNC_MOD_EXPR: /* round toward zero */
case EXACT_DIV_EXPR: /* for this one, it shouldn't matter */
! return;
case FLOOR_DIV_EXPR:
--- 692,696 ----
case TRUNC_MOD_EXPR: /* round toward zero */
case EXACT_DIV_EXPR: /* for this one, it shouldn't matter */
! return overflow;
case FLOOR_DIV_EXPR:
***************
*** 651,655 ****
add_double (*lquo, *hquo, -1, -1, lquo, hquo);
}
! else return;
break;
--- 701,705 ----
add_double (*lquo, *hquo, -1, -1, lquo, hquo);
}
! else return overflow;
break;
***************
*** 660,664 ****
add_double (*lquo, *hquo, 1, 0, lquo, hquo);
}
! else return;
break;
--- 710,714 ----
add_double (*lquo, *hquo, 1, 0, lquo, hquo);
}
! else return overflow;
break;
***************
*** 686,690 ****
add_double (*lquo, *hquo, 1, 0, lquo, hquo);
}
! else return;
}
break;
--- 736,740 ----
add_double (*lquo, *hquo, 1, 0, lquo, hquo);
}
! else return overflow;
}
break;
***************
*** 698,701 ****
--- 748,752 ----
neg_double (*lrem, *hrem, lrem, hrem);
add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
+ return overflow;
}
***************
*** 957,960 ****
--- 1008,1012 ----
register tree t;
int uns = TREE_UNSIGNED (TREE_TYPE (arg1));
+ int overflow = 0;
switch (code)
***************
*** 979,986 ****
int2l = - int2l;
case LSHIFT_EXPR:
! lshift_double (int1l, int1h, int2l,
! TYPE_PRECISION (TREE_TYPE (arg1)),
! &low, &hi,
! !uns);
t = build_int_2 (low, hi);
break;
--- 1031,1038 ----
int2l = - int2l;
case LSHIFT_EXPR:
! overflow = lshift_double (int1l, int1h, int2l,
! TYPE_PRECISION (TREE_TYPE (arg1)),
! &low, &hi,
! !uns);
t = build_int_2 (low, hi);
break;
***************
*** 1000,1004 ****
int2l += int1l;
if ((unsigned) int2l < int1l)
! int2h += 1;
t = build_int_2 (int2l, int2h);
break;
--- 1052,1056 ----
int2l += int1l;
if ((unsigned) int2l < int1l)
! overflow = int2h++ >= 0 && int2h < 0;
t = build_int_2 (int2l, int2h);
break;
***************
*** 1008,1016 ****
int1l += int2l;
if ((unsigned) int1l < int2l)
! int1h += 1;
t = build_int_2 (int1l, int1h);
break;
}
! add_double (int1l, int1h, int2l, int2h, &low, &hi);
t = build_int_2 (low, hi);
break;
--- 1060,1068 ----
int1l += int2l;
if ((unsigned) int1l < int2l)
! overflow = int1h++ >= 0 && int1h < 0;
t = build_int_2 (int1l, int1h);
break;
}
! overflow = add_double (int1l, int1h, int2l, int2h, &low, &hi);
t = build_int_2 (low, hi);
break;
***************
*** 1022,1027 ****
break;
}
! neg_double (int2l, int2h, &int2l, &int2h);
! add_double (int1l, int1h, int2l, int2h, &low, &hi);
t = build_int_2 (low, hi);
break;
--- 1074,1080 ----
break;
}
! neg_double (int2l, int2h, &low, &hi);
! add_double (int1l, int1h, low, hi, &low, &hi);
! overflow = !possible_sum_sign (hi, int2h, int1h);
t = build_int_2 (low, hi);
break;
***************
*** 1042,1052 ****
goto got_it;
case 2:
temp = int2l + int2l;
! int2h = int2h * 2 + (temp < int2l);
t = build_int_2 (temp, int2h);
goto got_it;
case 4:
temp = int2l + int2l;
! int2h = int2h * 4 + ((temp < int2l) << 1);
int2l = temp;
temp += temp;
--- 1095,1107 ----
goto got_it;
case 2:
+ overflow = left_shift_overflows (int2h, 1);
temp = int2l + int2l;
! int2h = (int2h << 1) + (temp < int2l);
t = build_int_2 (temp, int2h);
goto got_it;
case 4:
+ overflow = left_shift_overflows (int2h, 2);
temp = int2l + int2l;
! int2h = (int2h << 2) + ((temp < int2l) << 1);
int2l = temp;
temp += temp;
***************
*** 1055,1060 ****
goto got_it;
case 8:
temp = int2l + int2l;
! int2h = int2h * 8 + ((temp < int2l) << 2);
int2l = temp;
temp += temp;
--- 1110,1116 ----
goto got_it;
case 8:
+ overflow = left_shift_overflows (int2h, 3);
temp = int2l + int2l;
! int2h = (int2h << 3) + ((temp < int2l) << 2);
int2l = temp;
temp += temp;
***************
*** 1084,1088 ****
}
! mul_double (int1l, int1h, int2l, int2h, &low, &hi);
t = build_int_2 (low, hi);
break;
--- 1140,1144 ----
}
! overflow = mul_double (int1l, int1h, int2l, int2h, &low, &hi);
t = build_int_2 (low, hi);
break;
***************
*** 1115,1120 ****
break;
}
! div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
! &low, &hi, &garbagel, &garbageh);
t = build_int_2 (low, hi);
break;
--- 1171,1177 ----
break;
}
! overflow = div_and_round_double (code, uns,
! int1l, int1h, int2l, int2h,
! &low, &hi, &garbagel, &garbageh);
t = build_int_2 (low, hi);
break;
***************
*** 1122,1127 ****
case TRUNC_MOD_EXPR: case ROUND_MOD_EXPR:
case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
! div_and_round_double (code, uns, int1l, int1h, int2l, int2h,
! &garbagel, &garbageh, &low, &hi);
t = build_int_2 (low, hi);
break;
--- 1179,1185 ----
case TRUNC_MOD_EXPR: case ROUND_MOD_EXPR:
case FLOOR_MOD_EXPR: case CEIL_MOD_EXPR:
! overflow = div_and_round_double (code, uns,
! int1l, int1h, int2l, int2h,
! &garbagel, &garbageh, &low, &hi);
t = build_int_2 (low, hi);
break;
***************
*** 1152,1156 ****
got_it:
TREE_TYPE (t) = TREE_TYPE (arg1);
! force_fit_type (t);
return t;
}
--- 1210,1214 ----
got_it:
TREE_TYPE (t) = TREE_TYPE (arg1);
! force_fit_type (t, overflow);
return t;
}
***************
*** 1167,1171 ****
if (setjmp (float_error))
{
! warning ("floating overflow in constant folding");
return build (code, TREE_TYPE (arg1), arg1, arg2);
}
--- 1225,1229 ----
if (setjmp (float_error))
{
! pedwarn ("floating overflow in constant expression");
return build (code, TREE_TYPE (arg1), arg1, arg2);
}
***************
*** 1359,1363 ****
TREE_INT_CST_HIGH (arg1));
TREE_TYPE (t) = type;
! force_fit_type (t);
}
#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
--- 1417,1421 ----
TREE_INT_CST_HIGH (arg1));
TREE_TYPE (t) = type;
! force_fit_type (t, 0);
}
#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
***************
*** 1377,1381 ****
if (! (REAL_VALUES_LESS (l, x) && REAL_VALUES_LESS (x, u)))
{
! warning ("real constant out of range for integer conversion");
return t;
}
--- 1435,1439 ----
if (! (REAL_VALUES_LESS (l, x) && REAL_VALUES_LESS (x, u)))
{
! pedwarn ("real constant out of range for integer conversion");
return t;
}
***************
*** 1405,1409 ****
#endif
TREE_TYPE (t) = type;
! force_fit_type (t);
}
#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
--- 1463,1467 ----
#endif
TREE_TYPE (t) = type;
! force_fit_type (t, 0);
}
#endif /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
***************
*** 1420,1424 ****
if (setjmp (float_error))
{
! warning ("floating overflow in constant folding");
return t;
}
--- 1478,1482 ----
if (setjmp (float_error))
{
! pedwarn ("floating overflow in constant expression");
return t;
}
***************
*** 2805,2809 ****
t = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0);
TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (arg0));
! force_fit_type (t);
}
}
--- 2863,2867 ----
t = build_int_2 (TREE_STRING_POINTER (arg0)[i], 0);
TREE_TYPE (t) = TREE_TYPE (TREE_TYPE (arg0));
! force_fit_type (t, 0);
}
}
***************
*** 2820,2830 ****
if (TREE_CODE (arg0) == INTEGER_CST)
{
! if (TREE_INT_CST_LOW (arg0) == 0)
! t = build_int_2 (0, - TREE_INT_CST_HIGH (arg0));
! else
! t = build_int_2 (- TREE_INT_CST_LOW (arg0),
! ~ TREE_INT_CST_HIGH (arg0));
TREE_TYPE (t) = type;
! force_fit_type (t);
}
else if (TREE_CODE (arg0) == REAL_CST)
--- 2878,2888 ----
if (TREE_CODE (arg0) == INTEGER_CST)
{
! int low, high;
! int overflow = neg_double (TREE_INT_CST_LOW (arg0),
! TREE_INT_CST_HIGH (arg0),
! &low, &high);
! t = build_int_2 (low, high);
TREE_TYPE (t) = type;
! force_fit_type (t, overflow);
}
else if (TREE_CODE (arg0) == REAL_CST)
***************
*** 2876,2880 ****
~ TREE_INT_CST_HIGH (arg0));
TREE_TYPE (t) = type;
! force_fit_type (t);
}
else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
--- 2934,2938 ----
~ TREE_INT_CST_HIGH (arg0));
TREE_TYPE (t) = type;
! force_fit_type (t, 0);
}
else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
===================================================================
RCS file: tree.h,v
retrieving revision 2.2.2.1
diff -c2 -r2.2.2.1 tree.h
*** tree.h 1992/06/21 05:34:02 2.2.2.1
--- tree.h 1992/09/03 02:15:57
***************
*** 219,224 ****
#define TREE_NO_UNUSED_WARNING(NODE) ((NODE)->common.static_flag)
! /* In a NON_LVALUE_EXPR, this means there was overflow in folding.
! The folded constant is inside the NON_LVALUE_EXPR. */
#define TREE_CONSTANT_OVERFLOW(NODE) ((NODE)->common.static_flag)
--- 219,223 ----
#define TREE_NO_UNUSED_WARNING(NODE) ((NODE)->common.static_flag)
! /* In an INTEGER_CST, this means there was overflow in folding. */
#define TREE_CONSTANT_OVERFLOW(NODE) ((NODE)->common.static_flag)
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads