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]

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


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  <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]