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)