From 158cdc7bd97d7ccca5bc8adaaf80fe51eacdc038 Mon Sep 17 00:00:00 2001 From: Martin Sebor <msebor@redhat.com> Date: Tue, 4 May 2021 13:46:37 -0600 Subject: [PATCH] PR middle-end/100307 - spurious -Wplacement-new with negative pointer offset gcc/ChangeLog: PR middle-end/100307 * builtins.c (compute_objsize_r): Clear base0 for pointers. gcc/testsuite/ChangeLog: PR middle-end/100307 * g++.dg/warn/Wplacement-new-size-9.C: New test. * gcc.dg/tree-ssa/builtin-sprintf-warn-26.c: New test. --- gcc/builtins.c | 4 +- .../g++.dg/warn/Wplacement-new-size-9.C | 39 +++++++++++++++++++ .../gcc.dg/tree-ssa/builtin-sprintf-warn-26.c | 38 ++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wplacement-new-size-9.C create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c diff --git a/gcc/builtins.c b/gcc/builtins.c index 0db4090c434e..6f67eb7eeb55 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -5447,8 +5447,10 @@ compute_objsize_r (tree ptr, int ostype, access_ref *pref, if (!addr && POINTER_TYPE_P (TREE_TYPE (ptr))) { /* Set the maximum size if the reference is to the pointer - itself (as opposed to what it points to). */ + itself (as opposed to what it points to), and clear + BASE0 since the offset isn't necessarily zero-based. */ pref->set_max_size_range (); + pref->base0 = false; return true; } diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-9.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-9.C new file mode 100644 index 000000000000..a6b5870be645 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-9.C @@ -0,0 +1,39 @@ +/* PR middle-end/100307 - spurious -Wplacement-new with negative pointer + offset + { dg-do compile } + { dg-options "-O0 -Wall" } */ + +void* operator new (__SIZE_TYPE__, void *p) { return p; } +void* operator new[] (__SIZE_TYPE__, void *p) { return p; } + +static char a[2]; + +void* nowarn_scalar () +{ + char* p = a + 1; + char *q = new (p - 1) char (); // { dg-bogus "-Wplacement-new" } + return q; +} + + +void* nowarn_array () +{ + char* p = a + 1; + char *q = new (p - 1) char[2]; // { dg-bogus "-Wplacement-new" } + return q; +} + +void* warn_scalar () +{ + char* p = a + 1; + char *q = new (p - 2) char (); // { dg-warning "-Wplacement-new" "pr100325" { xfail *-*-* } } + return q; +} + + +void* warn_array () +{ + char* p = a + 1; + char *q = new (p - 1) char[2]; // { dg-warning "-Wplacement-new" "pr100325" { xfail *-*-* } } + return q; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c new file mode 100644 index 000000000000..16a551d9c8da --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-26.c @@ -0,0 +1,38 @@ +/* PR middle-end/100307 - spurious -Wplacement-new with negative pointer + offset + { dg-do compile } + { dg-options "-O0 -Wall" } */ + +extern int sprintf (char*, const char*, ...); + +char a[4]; + +void nowarn_1m1 () +{ + char *p = a + 1; + sprintf (p - 1, "%i", 123); // { dg-bogus "-Wformat-overflow" } +} + +void nowarn_4m3 () +{ + char *p = a + 4; + sprintf (p - 3, "%i", 12); // { dg-bogus "-Wformat-overflow" } +} + +void warn_2m1 () +{ + char *p = a + 2; + sprintf (p - 1, "%i", 123); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } +} + +void warn_3m1 () +{ + char *p = a + 3; + sprintf (p - 1, "%i", 12); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } +} + +void warn_4m1 () +{ + char *p = a + 4; + sprintf (p - 1, "%i", 1); // { dg-warning "-Wformat-overflow" "pr100325" { xfail *-*-* } } +} -- GitLab