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]

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


Hi Roger,

I am trying to integrate your patch with my patch at
http://gcc.gnu.org/ml/gcc-patches/2006-11/msg00248.html to avoid
conflicts.

I must admit that I don't fully understand what you are testing. For
example, in convert_and_check() you add a big condition at the
beginning:

!   if (TREE_CODE (expr) == INTEGER_CST
!       && (TREE_CODE (type) == INTEGER_TYPE
!         || TREE_CODE (type) == ENUMERAL_TYPE)
!       && !int_fits_type_p (expr, type))

then later within the body of that condition you test for:

!         else if (pedantic
!                  && (TREE_CODE (TREE_TYPE (expr)) != INTEGER_TYPE
!                      || TYPE_PRECISION (TREE_TYPE (expr))
!                         != TYPE_PRECISION (type)))

How can TREE_CODE (expr) == INTEGER_CST and TREE_CODE (TREE_TYPE
(expr)) != INTEGER_TYPE be true at the same time?

Cheers,

Manuel.

On 12/11/06, Roger Sayle <roger@eyesopen.com> wrote:

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]