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

Manuel López-Ibáñez lopezibanez@gmail.com
Thu Nov 16 14:27:00 GMT 2006


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



More information about the Gcc-patches mailing list