[C++ PATCH] Fix ICE in warn_placement_new_too_small (PR c++/70488)

Martin Sebor msebor@gmail.com
Fri Apr 1 15:28:00 GMT 2016


On 04/01/2016 09:11 AM, Jakub Jelinek wrote:
> 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?

Thanks for the patch!  I suspect the loop was either a thinko
or the result of moving code around while in development, or
both.  I do remember meaning to revisit the loop because it
didn't make complete sense even to me but forgot to get back
to it.  Let me look into cleaning it up after I'm done with
what I'm working on now.

Martin

>
> 2016-04-01  Jakub Jelinek  <jakub@redhat.com>
> 	    Marek Polacek  <polacek@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
>



More information about the Gcc-patches mailing list