PR c++/71306 - bogus -Wplacement-new with an array element
authorMartin Sebor <msebor@redhat.com>
Mon, 30 May 2016 22:56:43 +0000 (22:56 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Mon, 30 May 2016 22:56:43 +0000 (16:56 -0600)
gcc/cp/ChangeLog:
2016-05-27  Martin Sebor  <msebor@redhat.com>

PR c++/71306
* init.c (warn_placement_new_too_small): Handle placement new arguments
that are elements of arrays more carefully.  Remove a pointless loop.

gcc/testsuite/ChangeLog:
2016-05-27  Martin Sebor  <msebor@redhat.com>

PR c++/71306
* g++.dg/warn/Wplacement-new-size-3.C: New test.

From-SVN: r236902

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/Wplacement-new-size-3.C [new file with mode: 0644]

index 1e4ca0c347180b5acd3a30fb58e6273fc0d29f41..266ca0adcbe6097577f434d5a08d3c98045a2b92 100644 (file)
@@ -1,3 +1,9 @@
+2016-05-27  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/71306
+       * init.c (warn_placement_new_too_small): Handle placement new arguments
+       that are elements of arrays more carefully.  Remove a pointless loop.
+
 2016-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/71349
index 8e7541fcf987c66c8f16a411b86bd4a334d65f05..a71c21aed908bb6f936f6fff3d0ea801aa40ce6c 100644 (file)
@@ -2376,7 +2376,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
 
   STRIP_NOPS (oper);
 
-  if (TREE_CODE (oper) == ARRAY_REF)
+  if (TREE_CODE (oper) == ARRAY_REF
+      && (addr_expr || TREE_CODE (TREE_TYPE (oper)) == ARRAY_TYPE))
     {
       /* Similar to the offset computed above, see if the array index
         is a compile-time constant.  If so, and unless the offset was
@@ -2405,8 +2406,8 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
   bool compref = TREE_CODE (oper) == COMPONENT_REF;
 
   /* Descend into a struct or union to find the member whose address
-     is being used as the agument.  */
-  while (TREE_CODE (oper) == COMPONENT_REF)
+     is being used as the argument.  */
+  if (TREE_CODE (oper) == COMPONENT_REF)
     {
       tree op0 = oper;
       while (TREE_CODE (op0 = TREE_OPERAND (op0, 0)) == COMPONENT_REF);
index d9ef789ba1f53dd3a00954ceca3fbbc9c5bbbf87..dfcd4464b9a5e3539dae225c36046dc7f75aa8f0 100644 (file)
@@ -1,3 +1,8 @@
+2016-05-27  Martin Sebor  <msebor@redhat.com>
+
+       PR c++/71306
+       * g++.dg/warn/Wplacement-new-size-3.C: New test.
+
 2016-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/71349
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-3.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-3.C
new file mode 100644 (file)
index 0000000..c93e4e6
--- /dev/null
@@ -0,0 +1,40 @@
+// PR c++/71306 - bogus -Wplacement-new with an array element
+// { dg-do compile }
+// { dg-options "-Wplacement-new" }
+
+void* operator new (__SIZE_TYPE__, void *p) { return p; }
+
+struct S64 { char c [64]; };
+
+S64 s2 [2];
+S64* ps2 [2];
+S64* ps2_2 [2][2];
+
+void* pv2 [2];
+
+void f ()
+{
+  char a [2][sizeof (S64)];
+
+  new (a) S64;
+  new (a [0]) S64;
+  new (a [1]) S64;
+
+  // Verify there is no warning with buffers of sufficient size.
+  new (&s2 [0]) S64;
+  new (&s2 [1]) S64;
+
+  // ..and no warning with pointers to buffers of unknown size.
+  new (ps2 [0]) S64;
+  new (ps2 [1]) S64;
+
+  // But a warning when using the ps2_2 array itself as opposed
+  // to the pointers it's elements might point to.
+  new (ps2_2 [0]) S64; // { dg-warning "placement new" }
+  new (ps2_2 [1]) S64; // { dg-warning "placement new" }
+
+  // ..and no warning again with pointers to buffers of unknown
+  // size.
+  new (pv2 [0]) S64;
+  new (pv2 [1]) S64;
+}