Hi! The new warn_placement_new_too_small function blindly assumes that if {DECL,TYPE}_SIZE_UNIT is non-NULL, then it must be INTEGER_CST that fits into uhwi. That is not the case, it could be a VLA, etc.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? OT, as I said in bugzilla, I see very questionable code in that function too, no idea what Martin meant with that: while (TREE_CODE (oper) == COMPONENT_REF) { tree op0 = oper; while (TREE_CODE (op0 = TREE_OPERAND (op0, 0)) == COMPONENT_REF); if (TREE_CODE (op0) == VAR_DECL) var_decl = op0; oper = TREE_OPERAND (oper, 1); } TREE_OPERAND (oper, 1) of a COMPONENT_REF should be always a FIELD_DECL, so this will never loop. Did you mean to use if instead of while, something different? 2016-04-01 Jakub Jelinek <ja...@redhat.com> Marek Polacek <pola...@redhat.com> PR c++/70488 * init.c (warn_placement_new_too_small): Test whether DECL_SIZE_UNIT or TYPE_SIZE_UNIT are integers that fit into uhwi. * g++.dg/init/new47.C: New test. --- gcc/cp/init.c.jj 2016-03-31 10:55:58.000000000 +0200 +++ gcc/cp/init.c 2016-04-01 14:23:25.977800499 +0200 @@ -2430,7 +2430,8 @@ warn_placement_new_too_small (tree type, though the size of a member of a union may be viewed as extending to the end of the union itself (it is by __builtin_object_size). */ if ((TREE_CODE (oper) == VAR_DECL || use_obj_size) - && DECL_SIZE_UNIT (oper)) + && DECL_SIZE_UNIT (oper) + && tree_fits_uhwi_p (DECL_SIZE_UNIT (oper))) { /* Use the size of the entire array object when the expression refers to a variable or its size depends on an expression @@ -2438,7 +2439,8 @@ warn_placement_new_too_small (tree type, bytes_avail = tree_to_uhwi (DECL_SIZE_UNIT (oper)); exact_size = !use_obj_size; } - else if (TYPE_SIZE_UNIT (TREE_TYPE (oper))) + else if (TYPE_SIZE_UNIT (TREE_TYPE (oper)) + && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (oper)))) { /* Use the size of the type of the destination buffer object as the optimistic estimate of the available space in it. */ --- gcc/testsuite/g++.dg/init/new47.C.jj 2016-04-01 14:36:20.516355623 +0200 +++ gcc/testsuite/g++.dg/init/new47.C 2016-04-01 14:36:34.162171718 +0200 @@ -0,0 +1,19 @@ +// PR c++/70448 +// { dg-do compile } +// { dg-options "-Wall" } + +typedef __typeof__ (sizeof 0) size_t; +void *operator new (size_t, void *p) { return p; } +void *operator new[] (size_t, void *p) { return p; } +struct S { size_t s; }; +void bar (S *); + +void +foo (unsigned int s) +{ + char t[sizeof (S) + s]; + S *f = new (t) S; + bar (f); + f = new (t) S[1]; + bar (f); +} Jakub