On Tue, 26 Feb 2019, Jakub Jelinek wrote:

> Hi!
> 
> Seems valid_constant_size_p has been written with the expectation that only
> sizetype/ssizetype constants will be passed to it, otherwise it couldn't
> ever just blindly test tree_int_cst_sign_bit (size) for unsigned
> INTEGER_CSTs and complain cst_size_too_big.
> Unfortunately a recent patch started using this function even on other
> types, and the comment explicitly talk about it being done on
> pre-conversion to sizetype:
>       /* The expression in a noptr-new-declarator is erroneous if it's of
>          non-class type and its value before converting to std::size_t is
>          less than zero. ... If the expression is a constant expression,
>          the program is ill-fomed.  */
>       if (TREE_CODE (cst_nelts) == INTEGER_CST
>           && !valid_array_size_p (input_location, cst_nelts, NULL_TREE,
>                                   complain & tf_error))
>         return error_mark_node;
> E.g. __int128 negative value could fit just fine after cast to sizetype,
> etc.
> 
> So, instead of changing the C++ FE to only complain about negative cst_elts
> normally and fold_convert everything to sizetype before checking, this patch
> attempts to deal with non-{,s}sizetype constants.  Negative (signed)
> constants are always rejected as before, newly constants that don't fit into
> uhwi are rejected after that check regardless of signedness and anything
> larger or equal than SIZE_MAX / 2 is also rejected as too big.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

> 2019-02-26  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR c++/89507
>       * tree.c (valid_constant_size_p): Deal with size INTEGER_CSTs
>       with types other than sizetype/ssizetype.
> 
>       * g++.dg/other/new2.C: New test.
> 
> --- gcc/tree.c.jj     2019-02-18 20:48:35.745681423 +0100
> +++ gcc/tree.c        2019-02-26 18:22:23.760753681 +0100
> @@ -7533,19 +7533,16 @@ valid_constant_size_p (const_tree size,
>        return false;
>      }
>  
> -  tree type = TREE_TYPE (size);
> -  if (TYPE_UNSIGNED (type))
> +  if (tree_int_cst_sgn (size) < 0)
>      {
> -      if (!tree_fits_uhwi_p (size)
> -       || tree_int_cst_sign_bit (size))
> -     {
> -       *perr = cst_size_too_big;
> -       return false;
> -     }
> +      *perr = cst_size_negative;
> +      return false;
>      }
> -  else if (tree_int_cst_sign_bit (size))
> +  if (!tree_fits_uhwi_p (size)
> +      || (wi::to_widest (TYPE_MAX_VALUE (sizetype))
> +       < wi::to_widest (size) * 2))
>      {
> -      *perr = cst_size_negative;
> +      *perr = cst_size_too_big;
>        return false;
>      }
>  
> --- gcc/testsuite/g++.dg/other/new2.C.jj      2019-02-26 18:24:23.792785651 
> +0100
> +++ gcc/testsuite/g++.dg/other/new2.C 2019-02-26 18:23:26.530724514 +0100
> @@ -0,0 +1,5 @@
> +// PR c++/89507
> +// { dg-do compile }
> +
> +unsigned char const n = 128;
> +int *p = new int[n]; // { dg-bogus "array exceeds maximum object size" }
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to