This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR19100: truthvalue_conversion vs. TREE_OVERFLOW (take 3)
- From: Roger Sayle <roger at eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Mark Mitchell <mark at codesourcery dot com>
- Date: Sat, 1 Jan 2005 18:31:12 -0700 (MST)
- Subject: [PATCH] PR19100: truthvalue_conversion vs. TREE_OVERFLOW (take 3)
The following patch is my third attempt at resolving PR middle-end/19100
which is a wrong code bug affecting both C and C++ on mainline. I still
believe that the correct fix is to clean-up truthvalue_conversion, however
I also agree that reducing/eliminating TREE_OVERFLOW from GCC is a good
thing, so the patch below humours Mark's request to investigate a fix in
the middle-end. [It did however require two fixes to int_fits_type_p :)]
The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all default languages, and regression tested with a
top-level "make -k check" with no new failures.
Ok for mainline?
As described above, I'd also like to apply the truthvalue_conversion fixes
described at http://gcc.gnu.org/ml/gcc-patches/2004-12/msg01657.html
Ok for mainline too?
2005-01-01 Roger Sayle <roger@eyesopen.com>
PR middle-end/19100
* fold-const.c (fold_convert_const): Don't set TREE_OVERFLOW when
converting constants from one integer type to another.
* c-common.c (convert_and_check): Avoid testing TREE_OVERFLOW to
detect conversion overflow, instead use int_fits_type_p.
* gcc.dg/conv-3.c: New test case.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.486
diff -c -3 -p -r1.486 fold-const.c
*** fold-const.c 18 Dec 2004 19:03:49 -0000 1.486
--- fold-const.c 24 Dec 2004 02:52:17 -0000
*************** fold_convert_const (enum tree_code code,
*** 1730,1743 ****
t = build_int_cst_wide (type, TREE_INT_CST_LOW (arg1),
TREE_INT_CST_HIGH (arg1));
! t = force_fit_type (t,
! /* Don't set the overflow when
! converting a pointer */
! !POINTER_TYPE_P (TREE_TYPE (arg1)),
! (TREE_INT_CST_HIGH (arg1) < 0
! && (TYPE_UNSIGNED (type)
! < TYPE_UNSIGNED (TREE_TYPE (arg1))))
! | TREE_OVERFLOW (arg1),
TREE_CONSTANT_OVERFLOW (arg1));
return t;
}
--- 1730,1737 ----
t = build_int_cst_wide (type, TREE_INT_CST_LOW (arg1),
TREE_INT_CST_HIGH (arg1));
! /* We don't care about overflow in conversions. */
! t = force_fit_type (t, 0, TREE_OVERFLOW (arg1),
TREE_CONSTANT_OVERFLOW (arg1));
return t;
}
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.595
diff -c -3 -p -r1.595 c-common.c
*** c-common.c 20 Dec 2004 20:11:15 -0000 1.595
--- c-common.c 24 Dec 2004 02:52:18 -0000
*************** tree
*** 994,1024 ****
convert_and_check (tree type, tree expr)
{
tree t = convert (type, expr);
! if (TREE_CODE (t) == INTEGER_CST)
! {
! if (TREE_OVERFLOW (t))
! {
! TREE_OVERFLOW (t) = 0;
!
! /* Do not diagnose overflow in a constant expression merely
! because a conversion overflowed. */
! TREE_CONSTANT_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (expr);
!
! /* No warning for converting 0x80000000 to int. */
! if (!(TYPE_UNSIGNED (type) < TYPE_UNSIGNED (TREE_TYPE (expr))
! && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
! && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr))))
! /* If EXPR fits in the unsigned version of TYPE,
! don't warn unless pedantic. */
! if ((pedantic
! || TYPE_UNSIGNED (type)
! || !constant_fits_type_p (expr,
! c_common_unsigned_type (type)))
! && skip_evaluation == 0)
! warning ("overflow in implicit constant conversion");
! }
! else
unsigned_conversion_warning (t, expr);
}
return t;
}
--- 994,1025 ----
convert_and_check (tree type, tree expr)
{
tree t = convert (type, expr);
! if (TREE_CODE (t) == INTEGER_CST
! && (TREE_OVERFLOW (t)
! || (TREE_CODE (expr) == INTEGER_CST
! && INTEGRAL_TYPE_P (type)
! && !int_fits_type_p (expr, type))))
! {
! TREE_OVERFLOW (t) = 0;
!
! /* Do not diagnose overflow in a constant expression merely
! because a conversion overflowed. */
! TREE_CONSTANT_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (expr);
!
! if (skip_evaluation)
! ;
! else if (TYPE_UNSIGNED (type))
unsigned_conversion_warning (t, expr);
+ /* No warning for converting 0x80000000 to int. */
+ else if (TYPE_UNSIGNED (TREE_TYPE (expr))
+ && TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
+ && TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (expr)))
+ ;
+ else if (pedantic
+ || warn_conversion
+ || !constant_fits_type_p (expr,
+ c_common_unsigned_type (type)))
+ warning ("overflow in implicit constant conversion");
}
return t;
}
/* PR middle-end/19100 */
/* { dg-do run } */
/* { dg-options "-O2" } */
void abort (void);
int test (int v)
{
return ((signed char) (v ? 0x100 : 0)) ? 17 : 18;
}
int main()
{
if (test (2) != 18)
abort ();
return 0;
}
Roger
--