On Mon, Apr 10, 2017 at 04:16:42PM -0600, Martin Sebor wrote:
> gcc/ChangeLog:
> 
>       PR middle-end/80364
>       * gimple-ssa-sprintf.c (get_int_range): Remove second argument and
>       always use the int type.
>       (directive::set_width, directive::set_precision, format_character):
>       Adjust.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR middle-end/80364
>       * gcc.dg/tree-ssa/builtin-sprintf-warn-16.c: New test.

> @@ -961,10 +962,16 @@ get_int_range (tree arg, tree type, HOST_WIDE_INT 
> *pmin, HOST_WIDE_INT *pmax,
>        /* True if the argument's range cannot be determined.  */
>        bool unknown = true;
>  
> -      type = TREE_TYPE (arg);
> +      tree argtype = TREE_TYPE (arg);
>  
> +      /* Ignore invalid arguments with greater precision that that
> +      of the expected type (e.g., in sprintf("%*i", 12LL, i)).
> +      They will have been detected and diagnosed by -Wformat and
> +      so it's not important to complicate this code to try to deal
> +      with them again.  */
>        if (TREE_CODE (arg) == SSA_NAME
> -       && TREE_CODE (type) == INTEGER_TYPE)
> +       && TREE_CODE (argtype) == INTEGER_TYPE

I think you want
          && INTEGRAL_TYPE_P (argtype)
here instead of that last line, the middle-end considers conversions between
integral types useless (except for bool vs. non-bool conversions if the
other type has precision != 1), so if one does:
enum E { E0 = -__INT_MAX__ - 1, E1 = 1, E2 = 2, E3 = 3, E4 = __INT_MAX__ };
  enum E e = ...;
  snprintf (... "...%.*s...", ..., e, ...);
then you could very well have there ENUMERAL_TYPE etc.

Ok for trunk with that change.

        Jakub

Reply via email to