This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]