aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-10-09 13:56:53 -0600
committerMartin Sebor <msebor@redhat.com>2020-10-12 09:04:49 -0600
commitde05c19d5fd661ae16dd75a895b49d32d12f5edc (patch)
tree05d9906c75f514094c4320b482f200787a34b9b6 /gcc/testsuite
parent71dbabccbfb295c87d91719fe72d9d60511c0b44 (diff)
downloadgcc-de05c19d5fd661ae16dd75a895b49d32d12f5edc.zip
gcc-de05c19d5fd661ae16dd75a895b49d32d12f5edc.tar.gz
gcc-de05c19d5fd661ae16dd75a895b49d32d12f5edc.tar.bz2
Correct handling of indices into arrays with elements larger than 1 (PR c++/96511)
Resolves: PR c++/96511 - Incorrect -Wplacement-new on POINTER_PLUS into an array with 4-byte elements PR middle-end/96384 - bogus -Wstringop-overflow= storing into multidimensional array with index in range gcc/ChangeLog: PR c++/96511 PR middle-end/96384 * builtins.c (get_range): Return full range of type when neither value nor its range is available. Fail for ranges inverted due to the signedness of offsets. (compute_objsize): Handle more special array members. Handle POINTER_PLUS_EXPR and VIEW_CONVERT_EXPR that come up in front end code. (access_ref::offset_bounded): Define new member function. * builtins.h (access_ref::eval): New data member. (access_ref::offset_bounded): New member function. (access_ref::offset_zero): New member function. (compute_objsize): Declare a new overload. * gimple-array-bounds.cc (array_bounds_checker::check_array_ref): Use enum special_array_member. * tree.c (component_ref_size): Use special_array_member. * tree.h (special_array_member): Define a new type. (component_ref_size): Change signature. gcc/cp/ChangeLog: PR c++/96511 PR middle-end/96384 * init.c (warn_placement_new_too_small): Call builtin_objsize instead of duplicating what it does. gcc/testsuite/ChangeLog: PR c++/96511 PR middle-end/96384 * g++.dg/init/strlen.C: Add expected warning. * g++.dg/warn/Wplacement-new-size-1.C: Relax warnings. * g++.dg/warn/Wplacement-new-size-2.C: Same. * g++.dg/warn/Wplacement-new-size-6.C: Same. * gcc.dg/Warray-bounds-58.c: Adjust * gcc.dg/Wstringop-overflow-37.c: Same. * g++.dg/warn/Wplacement-new-size-7.C: New test.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r--gcc/testsuite/g++.dg/init/strlen.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C14
-rw-r--r--gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C18
-rw-r--r--gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C25
-rw-r--r--gcc/testsuite/g++.dg/warn/Wplacement-new-size-7.C82
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-58.c14
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-37.c20
7 files changed, 145 insertions, 30 deletions
diff --git a/gcc/testsuite/g++.dg/init/strlen.C b/gcc/testsuite/g++.dg/init/strlen.C
index aa8950e..cc650d6 100644
--- a/gcc/testsuite/g++.dg/init/strlen.C
+++ b/gcc/testsuite/g++.dg/init/strlen.C
@@ -29,7 +29,7 @@ test_dynamic_type (S *p)
// distinguish invalid cases from ones like it that might be valid.
// If/when GIMPLE changes to make this possible this test can be
// removed.
- char *q = new (p->a) char [16];
+ char *q = new (p->a) char [16]; // { dg-warning "\\\[-Wplacement-new" }
init (q);
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C
index d2ec608..cec8316 100644
--- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C
+++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-1.C
@@ -66,8 +66,9 @@ struct BA2 { int i; A2 a2; };
void fBx (BAx *pbx, BAx &rbx)
{
BAx bax;
- new (bax.ax.a) char; // { dg-warning "placement" }
- new (bax.ax.a) Int16; // { dg-warning "placement" }
+ // The uninitialized flexible array takes up the bytes of padding.
+ new (bax.ax.a) char;
+ new (bax.ax.a) Int16;
new (bax.ax.a) Int32; // { dg-warning "placement" }
new (pbx->ax.a) char;
@@ -84,9 +85,12 @@ void fBx1 ()
{
static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
- new (bax1.ax.a) char; // { dg-warning "placement" }
- new (bax1.ax.a) char[2]; // { dg-warning "placement" }
- new (bax1.ax.a) Int16; // { dg-warning "placement" }
+ // The empty flexible array takes up the bytes of padding.
+ new (bax1.ax.a) char;
+ new (bax1.ax.a) char[2];
+ new (bax1.ax.a) Int16;
+ new (bax1.ax.a) char[3];
+ new (bax1.ax.a) char[4]; // { dg-warning "placement" }
new (bax1.ax.a) Int32; // { dg-warning "placement" }
}
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C
index e00515e..e5fdfe1 100644
--- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C
+++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-2.C
@@ -124,9 +124,13 @@ struct BA2 { int i; A2 a2; };
void fBx (BAx *pbx, BAx &rbx)
{
BAx bax;
- new (bax.ax.a) char; // { dg-warning "placement" }
- new (bax.ax.a) Int16; // { dg-warning "placement" }
+ // The uninitialized flexible array takes up the bytes of padding.
+ new (bax.ax.a) char;
+ new (bax.ax.a) Int16;
+ new (bax.ax.a) char[3];
new (bax.ax.a) Int32; // { dg-warning "placement" }
+ new (bax.ax.a) char[4]; // { dg-warning "placement" }
+ new (bax.ax.a) char[5]; // { dg-warning "placement" }
new (pbx->ax.a) char;
new (rbx.ax.a) char;
@@ -142,10 +146,14 @@ void fBx1 ()
{
static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ {} } };
- new (bax1.ax.a) char; // { dg-warning "placement" }
- new (bax1.ax.a) char[2]; // { dg-warning "placement" }
- new (bax1.ax.a) Int16; // { dg-warning "placement" }
+ // The empty flexible array takes up the bytes of padding.
+ new (bax1.ax.a) char;
+ new (bax1.ax.a) char[2];
+ new (bax1.ax.a) Int16;
+ new (bax1.ax.a) char[3];
new (bax1.ax.a) Int32; // { dg-warning "placement" }
+ new (bax1.ax.a) char[4]; // { dg-warning "placement" }
+ new (bax1.ax.a) char[5]; // { dg-warning "placement" }
}
void fB0 (BA0 *pb0, BA0 &rb0)
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C
index b6a72b1..5eb63d2 100644
--- a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C
+++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-6.C
@@ -17,9 +17,10 @@ void fBx1 ()
{
static BAx bax1 = { 1, /* Ax = */ { 2, /* a[] = */ { 3 } } }; // { dg-error "initialization of flexible array member in a nested context" }
- new (bax1.ax.a) char; // { dg-warning "placement" }
- new (bax1.ax.a) char[2]; // { dg-warning "placement" }
- new (bax1.ax.a) Int16; // { dg-warning "placement" }
+ // The first three bytes of the flexible array member live in the padding.
+ new (bax1.ax.a) char;
+ new (bax1.ax.a) char[2];
+ new (bax1.ax.a) Int16;
new (bax1.ax.a) Int32; // { dg-warning "placement" }
}
@@ -27,10 +28,11 @@ void fBx2 ()
{
static BAx bax2 = { 1, /* Ax = */ { 2, /* a[] = */ { 3, 4 } } }; // { dg-error "initialization of flexible array member in a nested context" }
- new (bax2.ax.a) char; // { dg-warning "placement" }
- new (bax2.ax.a) char[2]; // { dg-warning "placement" }
- new (bax2.ax.a) char[3]; // { dg-warning "placement" }
- new (bax2.ax.a) Int16; // { dg-warning "placement" }
+ // The first three bytes of the flexible array member live in the padding.
+ new (bax2.ax.a) char;
+ new (bax2.ax.a) char[2];
+ new (bax2.ax.a) char[3];
+ new (bax2.ax.a) Int16;
new (bax2.ax.a) char[4]; // { dg-warning "placement" }
new (bax2.ax.a) Int32; // { dg-warning "placement" }
}
@@ -39,10 +41,11 @@ void fBx3 ()
{
static BAx bax2 = { 1, /* Ax = */ { 3, /* a[] = */ { 4, 5, 6 } } }; // { dg-error "initialization of flexible array member in a nested context" }
- new (bax2.ax.a) char; // { dg-warning "placement" }
- new (bax2.ax.a) char[2]; // { dg-warning "placement" }
- new (bax2.ax.a) Int16; // { dg-warning "placement" }
- new (bax2.ax.a) char[3]; // { dg-warning "placement" }
+ // The first three bytes of the flexible array member live in the padding.
+ new (bax2.ax.a) char;
+ new (bax2.ax.a) char[2];
+ new (bax2.ax.a) Int16;
+ new (bax2.ax.a) char[3];
new (bax2.ax.a) char[4]; // { dg-warning "placement" }
new (bax2.ax.a) Int32; // { dg-warning "placement" }
}
diff --git a/gcc/testsuite/g++.dg/warn/Wplacement-new-size-7.C b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-7.C
new file mode 100644
index 0000000..82f298d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wplacement-new-size-7.C
@@ -0,0 +1,82 @@
+/* PR c++/96511 - Incorrect -Wplacement-new on POINTER_PLUS into an array
+ with 4-byte elements
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __SIZE_TYPE__ size_t;
+
+void* operator new (size_t, void *p) { return p; }
+
+void test_a1_int16 ()
+{
+ int16_t a3[3]; // { dg-message "declared here" }
+
+ new (a3) int16_t;
+ new (a3 + 1) int16_t;
+ new (a3 + 2) int16_t; // { dg-bogus "\\\[-Wplacement-new" }
+ new (&a3[1]) int16_t;
+ new (&a3[0] + 1) int16_t;
+ new (&a3[0] + 2) int16_t; // { dg-bogus "\\\[-Wplacement-new" }
+ new (&a3[0] + 3) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+}
+
+void test_a1_int32 ()
+{
+ int16_t a3[3];
+
+ new (a3 + 1) int32_t; // { dg-bogus "\\\[-Wplacement-new" }
+ new (&a3[1]) int32_t;
+ new (&a3[0] + 1) int32_t; // { dg-bogus "\\\[-Wplacement-new" }
+ new (&a3[0] + 2) int32_t; // { dg-warning "\\\[-Wplacement-new" }
+}
+
+
+void test_a2 ()
+{
+ int16_t a23[2][3];
+
+ new (a23 + 1) int16_t; // { dg-bogus "\\\[-Wplacement-new" }
+ new (&a23[1]) int16_t;
+ new (&a23[2]) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+
+ new (&a23[0][0] + 1) int16_t;
+ new (&a23[0][0] + 2) int16_t;
+ // Deriving a pointer to the next array from one to an element of
+ // the prior array isn't valid even if the resulting pointer points
+ // to an element of the larger array. Verify it's diagnosed.
+ new (&a23[0][0] + 3) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][0] + 4) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][0] + 5) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][0] + 6) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+
+ new (&a23[0][1] + 1) int16_t;
+ new (&a23[0][1] + 2) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][1] + 3) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][1] + 4) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][1] + 5) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][1] + 6) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+
+ new (&a23[0][2] + 1) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][2] + 2) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][2] + 3) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][2] + 4) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][2] + 5) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[0][2] + 6) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+
+ new (&a23[1][0]) int16_t;
+ new (&a23[1][0] + 1) int16_t;
+ new (&a23[1][0] + 2) int16_t;
+ new (&a23[1][0] + 3) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[1][0] + 4) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+
+ new (&a23[1][1]) int16_t;
+ new (&a23[1][2]) int16_t;
+ new (&a23[1][2] + 1) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[1][3]) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[1][3] + 1) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+
+ new (&a23[2][0]) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+ new (&a23[2][0] + 1) int16_t; // { dg-warning "\\\[-Wplacement-new" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-58.c b/gcc/testsuite/gcc.dg/Warray-bounds-58.c
index 7c469e2..849457e5 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-58.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-58.c
@@ -1,5 +1,5 @@
/* { dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall -Wno-stringop-overread" } */
typedef __SIZE_TYPE__ size_t;
@@ -15,7 +15,7 @@ void fa0_extern (void)
{
sink (strlen (ea0.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ea0.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (ea0.a)); // { dg-warning "\\\[-Wstringop-overread" "pr93514" }
+ sink (strlen (ea0.a)); // valid just-past-the-end offset
sink (strlen (ea0.a + 1)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
}
@@ -25,7 +25,7 @@ void fa0_static (void)
{
sink (strlen (sa0.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (sa0.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (sa0.a)); // { dg-warning "\\\[-Wstringop-overread" "pr93514" }
+ sink (strlen (sa0.a)); // valid just-past-the-end offset
sink (strlen (sa0.a + 1)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
}
@@ -52,14 +52,14 @@ void fax_static (void)
sink (strlen (ax0.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ax0.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
sink (strlen (ax0.a));
- sink (strlen (ax0.a + 1)); // { dg-warning "\\\[-Wstringop-overread" "pr93514" }
+ sink (strlen (ax0.a + 1)); // valid just-past-the-end offset
sink (strlen (ax0.a + 2)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
sink (strlen (ax1.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ax1.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
sink (strlen (ax1.a));
sink (strlen (ax1.a + 1));
- sink (strlen (ax1.a + 2)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" "pr93514" }
+ sink (strlen (ax1.a + 2)); // valid just-past-the-end offset
sink (strlen (ax1.a + 3)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
sink (strlen (ax2.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
@@ -67,7 +67,7 @@ void fax_static (void)
sink (strlen (ax2.a));
sink (strlen (ax2.a + 1));
sink (strlen (ax2.a + 2));
- sink (strlen (ax2.a + 3)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" "pr93514" }
+ sink (strlen (ax2.a + 3)); // valid just-past-the-end offset
sink (strlen (ax2.a + 4)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
sink (strlen (ax3.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
@@ -76,6 +76,6 @@ void fax_static (void)
sink (strlen (ax3.a + 1));
sink (strlen (ax3.a + 2));
sink (strlen (ax3.a + 3));
- sink (strlen (ax3.a + 4)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" "pr93514" }
+ sink (strlen (ax3.a + 4)); // valid just-past-the-end offset
sink (strlen (ax3.a + 5)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
index 339f904..46f8fed 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
@@ -185,6 +185,18 @@ void test_note (const char *s)
}
{
+ char a[1][1][2]; // { dg-message "at offset 2 into " }
+ strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
+ sink (a);
+ }
+
+ {
+ char a[1][2][2]; // { dg-message "destination object" }
+ strncpy (a[0][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ sink (a);
+ }
+
+ {
char a[1][2][2]; // { dg-message "at offset 2 into " }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
@@ -192,7 +204,13 @@ void test_note (const char *s)
{
char a[1][2][2]; // { dg-message "at offset 4 into " }
- strncpy (a[1][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ strncpy (a[1][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
+ sink (a);
+ }
+
+ {
+ char a[2][1][2]; // { dg-message "at offset 2 into " }
+ strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}