This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]