c++: -Wplacement-new and anon union member [PR100370]
commit790b02af6a1fcfa07dba6129909b3578a55a51fa
authorJason Merrill <jason@redhat.com>
Wed, 6 Apr 2022 02:29:06 +0000 (5 22:29 -0400)
committerJason Merrill <jason@redhat.com>
Mon, 11 Apr 2022 12:37:03 +0000 (11 08:37 -0400)
tree866dc26b9e6c6429479a82e3981d21420d710251
parenta42aa68bf1ad745a6b36ab9beed1fc2e77ac3f88
c++: -Wplacement-new and anon union member [PR100370]

This bug was an object/value confusion; we are interested in the size
of *b.ip, but instead the code was calculating the size of b.ip itself.

This seems to be because compute_objsize will compute the size of whatever
object it can find in the argument: if you pass it a VAR_DECL, it gives you
the size of that variable.  If you pass it an ADDR_EXPR of a VAR_DECL, it
again gives you the size of the variable.  The way you can tell the
difference is by looking at the deref member of access_ref: if it's -1, the
argument is a pointer to the object.  Since that's what we're interested in,
we should check for that, like check_dangling_stores does.

This regressed some tests because compute_objsize_r was wrongly zeroing
deref in the POINTER_PLUS_EXPR handling; adding an offset to a pointer
doesn't change whether the pointer is itself a variable or a pointer to
one.  In fact, handling POINTER_PLUS_EXPR only really makes sense for deref
== -1, where we're adjusting a pointer to the variable.

PR c++/100370

gcc/cp/ChangeLog:

* init.cc (warn_placement_new_too_small): Check deref.

gcc/ChangeLog:

* pointer-query.cc (compute_objsize_r) [POINTER_PLUS_EXPR]: Require
deref == -1.

gcc/testsuite/ChangeLog:

* g++.dg/warn/Wplacement-new-size-11.C: New test.
gcc/cp/init.cc
gcc/pointer-query.cc
gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C [new file with mode: 0644]