* [PATCH RFA(pointer-query)] c++: -Wplacement-new and anon union member [PR100370]
@ 2022-04-06 14:25 Jason Merrill
2022-04-11 9:02 ` Richard Biener
0 siblings, 1 reply; 2+ messages in thread
From: Jason Merrill @ 2022-04-06 14:25 UTC (permalink / raw)
To: gcc-patches; +Cc: Martin Sebor
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.
Tested x86_64-pc-linux-gnu, OK for trunk?
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 | 5 +++++
gcc/pointer-query.cc | 7 ++++---
.../g++.dg/warn/Wplacement-new-size-11.C | 15 +++++++++++++++
3 files changed, 24 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 01e762320f3..43097121244 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -2811,6 +2811,11 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
if (!objsize)
return;
+ /* We can only draw conclusions if ref.deref == -1,
+ i.e. oper is the address of the object. */
+ if (ref.deref != -1)
+ return;
+
offset_int bytes_avail = wi::to_offset (objsize);
offset_int bytes_need;
diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
index 4390535ef56..d93657f3206 100644
--- a/gcc/pointer-query.cc
+++ b/gcc/pointer-query.cc
@@ -2299,9 +2299,10 @@ compute_objsize_r (tree ptr, gimple *stmt, bool addr, int ostype,
if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
return false;
- /* Clear DEREF since the offset is being applied to the target
- of the dereference. */
- pref->deref = 0;
+ /* The below only makes sense if the offset is being applied to the
+ address of the object. */
+ if (pref->deref != -1)
+ return false;
offset_int orng[2];
tree off = pref->eval (TREE_OPERAND (ptr, 1));
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C
new file mode 100644
index 00000000000..a6fe82e90ae
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C
@@ -0,0 +1,15 @@
+// PR c++/100370
+// { dg-do compile { target c++11 } }
+
+using size_t = decltype(sizeof(1));
+inline void *operator new (size_t s, void *p) { return p; }
+
+int main()
+{
+ struct s1 { int iv[4]; };
+ struct s2 { union { char* cp; int* ip; }; };
+
+ s2 b;
+ b.ip=new int[8];
+ new (b.ip+4) s1; // { dg-bogus "-Wplacement-new" }
+}
base-commit: 44fe49401725055a740ce47e80561b6932b8cd01
--
2.27.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH RFA(pointer-query)] c++: -Wplacement-new and anon union member [PR100370]
2022-04-06 14:25 [PATCH RFA(pointer-query)] c++: -Wplacement-new and anon union member [PR100370] Jason Merrill
@ 2022-04-11 9:02 ` Richard Biener
0 siblings, 0 replies; 2+ messages in thread
From: Richard Biener @ 2022-04-11 9:02 UTC (permalink / raw)
To: Jason Merrill; +Cc: GCC Patches, Martin Sebor
On Wed, Apr 6, 2022 at 4:26 PM Jason Merrill via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> 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.
>
> Tested x86_64-pc-linux-gnu, OK for trunk?
OK.
Thanks,
Richard.
> 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 | 5 +++++
> gcc/pointer-query.cc | 7 ++++---
> .../g++.dg/warn/Wplacement-new-size-11.C | 15 +++++++++++++++
> 3 files changed, 24 insertions(+), 3 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C
>
> diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
> index 01e762320f3..43097121244 100644
> --- a/gcc/cp/init.cc
> +++ b/gcc/cp/init.cc
> @@ -2811,6 +2811,11 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
> if (!objsize)
> return;
>
> + /* We can only draw conclusions if ref.deref == -1,
> + i.e. oper is the address of the object. */
> + if (ref.deref != -1)
> + return;
> +
> offset_int bytes_avail = wi::to_offset (objsize);
> offset_int bytes_need;
>
> diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc
> index 4390535ef56..d93657f3206 100644
> --- a/gcc/pointer-query.cc
> +++ b/gcc/pointer-query.cc
> @@ -2299,9 +2299,10 @@ compute_objsize_r (tree ptr, gimple *stmt, bool addr, int ostype,
> if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
> return false;
>
> - /* Clear DEREF since the offset is being applied to the target
> - of the dereference. */
> - pref->deref = 0;
> + /* The below only makes sense if the offset is being applied to the
> + address of the object. */
> + if (pref->deref != -1)
> + return false;
>
> offset_int orng[2];
> tree off = pref->eval (TREE_OPERAND (ptr, 1));
> diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C
> new file mode 100644
> index 00000000000..a6fe82e90ae
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-11.C
> @@ -0,0 +1,15 @@
> +// PR c++/100370
> +// { dg-do compile { target c++11 } }
> +
> +using size_t = decltype(sizeof(1));
> +inline void *operator new (size_t s, void *p) { return p; }
> +
> +int main()
> +{
> + struct s1 { int iv[4]; };
> + struct s2 { union { char* cp; int* ip; }; };
> +
> + s2 b;
> + b.ip=new int[8];
> + new (b.ip+4) s1; // { dg-bogus "-Wplacement-new" }
> +}
>
> base-commit: 44fe49401725055a740ce47e80561b6932b8cd01
> --
> 2.27.0
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2022-04-11 9:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-06 14:25 [PATCH RFA(pointer-query)] c++: -Wplacement-new and anon union member [PR100370] Jason Merrill
2022-04-11 9:02 ` Richard Biener
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).