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]

[C/C++ PATCH] Reorganize c-common.c's convert_and_check


This is one of the major installments in the on-going TREE_OVERFLOW
clean-ups.  Currently, when asked to truncate an INTEGER_CST to a
narrower type, the middle-end may set the TREE_OVERFLOW flag on the
result.  Even though the semantics of signed and unsigned truncation
are well-defined in the middle-end, the setting TREE_OVERFLOW has
historically been a source of problems in tree-ssa optimizers, as
it disables many transformations and triggers less well tested code
paths.

The propsed goal is to change fold_convert_const_int_from_int so
that it no longer sets TREE_OVERFLOW or TREE_CONSTANT_OVERFLOW.

The major remaining user of this functionality is the convert_and_check
function in the C family front-ends, that uses the TREE_OVERFLOW from
these truncations to issue front-end diagnostics.  It turns out that
its relatively simple to use the middle-end function int_fits_type
which is intended for exactly this use.  This reduces the overflow
bit pollution of trees in the tree-ssa optimizers.


The following patch has been tested (in conjunction with my recently
posted C++ clean-up) on x86_64-unknown-linux-gnu, with a full "make
bootstrap", all default languages, and regression tested with a
top-level "make -k check" with no new failures.  Critically, no
changes in the C/C++ diagnostics issued anywhere in the testsuite.

I believe that the rationalization of this logic in a single
front-end function, makes it easier to see what's going on, and
for front-end maintainers to tune as they wish.

Ok for mainline?  I'd appreciate it if anyone with access to Plum-Hall
or similar validation suite could give it a spin.  Hopefully, folks
agree this untangling of front-ends from the middle-end is a direction
that we want to go.



2006-11-12  Roger Sayle  <roger@eyesopen.com>

	* c-common.c (constant_fits_type_p): Delete.
	(unsigned_conversion_warning): Delete.  Integrate into...
	(convert_and_check): Reorganize and simplify to avoid dependence
	upon the middle-end setting TREE_OVERFLOW on integral conversions,
	by using int_fits_type directly.


Index: c-common.c
===================================================================
*** c-common.c	(revision 118625)
--- c-common.c	(working copy)
*************** const struct fname_var_t fname_vars[] =
*** 499,505 ****
    {NULL, 0, 0},
  };

- static int constant_fits_type_p (tree, tree);
  static tree check_case_value (tree);
  static bool check_case_bounds (tree, tree, tree *, tree *);

--- 499,504 ----
*************** overflow_warning (tree value)
*** 957,988 ****
      }
  }

- /* Print a warning if a large constant is truncated to unsigned,
-    or if -Wconversion is used and a constant < 0 is converted to unsigned.
-    Invoke this function on every expression that might be implicitly
-    converted to an unsigned type.  */
-
- static void
- unsigned_conversion_warning (tree result, tree operand)
- {
-   tree type = TREE_TYPE (result);
-
-   if (TREE_CODE (operand) == INTEGER_CST
-       && TREE_CODE (type) == INTEGER_TYPE
-       && TYPE_UNSIGNED (type)
-       && skip_evaluation == 0
-       && !int_fits_type_p (operand, type))
-     {
-       if (!int_fits_type_p (operand, c_common_signed_type (type)))
- 	/* This detects cases like converting -129 or 256 to unsigned char.  */
- 	warning (OPT_Woverflow,
- 		 "large integer implicitly truncated to unsigned type");
-       else
- 	warning (OPT_Wconversion,
- 		 "negative integer implicitly converted to unsigned type");
-     }
- }
-
  /* Print a warning about casts that might indicate violation
     of strict aliasing rules if -Wstrict-aliasing is used and
     strict aliasing mode is in effect. OTYPE is the original
--- 956,961 ----
*************** check_main_parameter_types (tree decl)
*** 1100,1118 ****
  }


- /* Nonzero if constant C has a value that is permissible
-    for type TYPE (an INTEGER_TYPE).  */
-
- static int
- constant_fits_type_p (tree c, tree type)
- {
-   if (TREE_CODE (c) == INTEGER_CST)
-     return int_fits_type_p (c, type);
-
-   c = convert (type, c);
-   return !TREE_OVERFLOW (c);
- }
-
  /* Nonzero if vector types T1 and T2 can be converted to each other
     without an explicit cast.  */
  int
--- 1073,1078 ----
*************** vector_types_convertible_p (tree t1, tre
*** 1134,1169 ****
  tree
  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) = CONSTANT_CLASS_P (expr)
!                                        && 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 (OPT_Woverflow,
!                        "overflow in implicit constant conversion");
  	}
        else
! 	unsigned_conversion_warning (t, expr);
      }
!   return t;
  }

  /* A node in a list that describes references to variables (EXPR), which are
--- 1094,1150 ----
  tree
  convert_and_check (tree type, tree expr)
  {
!   tree result;

!   if (TREE_TYPE (expr) == type)
!     return expr;

!   result = convert (type, expr);
!   if (TREE_CODE (result) != INTEGER_CST
!       || skip_evaluation)
!     return result;
!
!   if (TREE_CODE (expr) == INTEGER_CST
!       && (TREE_CODE (type) == INTEGER_TYPE
! 	  || TREE_CODE (type) == ENUMERAL_TYPE)
!       && !int_fits_type_p (expr, type))
!     {
!       /* Do not diagnose overflow in a constant expression merely
! 	 because a conversion overflowed.  */
!       if (TREE_OVERFLOW (result))
! 	{
! 	  TREE_CONSTANT_OVERFLOW (result) = TREE_CONSTANT_OVERFLOW (expr);
! 	  TREE_OVERFLOW (result) = TREE_OVERFLOW (expr);
! 	}
!
!       if (TYPE_UNSIGNED (type))
! 	{
! 	  /* This detects cases like converting -129 or 256 to
! 	     unsigned char.  */
! 	  if (!int_fits_type_p (expr, c_common_signed_type (type)))
! 	    warning (OPT_Woverflow,
! 		     "large integer implicitly truncated to unsigned type");
! 	  else
! 	    warning (OPT_Wconversion,
! 		     "negative integer implicitly converted to unsigned type");
  	}
        else
! 	{
! 	  if (!int_fits_type_p (expr, c_common_unsigned_type (type)))
! 	    warning (OPT_Woverflow,
! 		     "overflow in implicit constant conversion");
! 	  /* No warning for converting 0x80000000 to int.  */
! 	  else if (pedantic
! 		   && (TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE
! 		       || TYPE_PRECISION (TREE_TYPE (expr))
! 			  != TYPE_PRECISION (type)))
! 	    warning (OPT_Woverflow,
! 		     "overflow in implicit constant conversion");
! 	}
      }
!   else if (TREE_OVERFLOW (result))
!     warning (OPT_Woverflow, "overflow in implicit constant conversion");
!   return result;
  }

  /* A node in a list that describes references to variables (EXPR), which are


Roger
--


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