diff gcc/testsuite/c-c++-common/Wstringop-overflow-2.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/testsuite/c-c++-common/Wstringop-overflow-2.c	Thu Feb 13 11:34:05 2020 +0900
@@ -0,0 +1,348 @@
+/* PR middle-end/91458 - inconsistent warning for writing past the end
+   of an array member
+   { dg-do compile }
+   { dg-options "-O2 -Wall -Wno-array-bounds" } */
+
+void sink (void*);
+
+// Exercise flexible array members.
+
+struct Ax
+{
+  char n;
+  char a[];                     // { dg-message "declared here" }
+};
+
+// Verify warning for a definition with no initializer.
+struct Ax ax_;
+
+void gax_ (void)
+{
+  ax_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the flexible array member.
+struct Ax ax0 = { 0 };
+
+void gax0 (void)
+{
+  ax0.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the flexible array member to empty.
+struct Ax ax0_ = { 0, { } };
+
+void gax0_ (void)
+{
+  ax0_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  ax0_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for out-of-bounds accesses to a definition with
+// an initializer.
+struct Ax ax1 = { 1, { 0 } };
+
+void gax1 (void)
+{
+  ax1.a[0] = 0;
+  ax1.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  ax1.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+struct Ax ax2 = { 2, { 1, 0 } };
+
+void gax2 (void)
+{
+  ax2.a[0] = 0;
+  ax2.a[1] = 1;
+  ax2.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+
+// Verify no warning for an unknown struct object.
+void gaxp (struct Ax *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;
+  p->a[9] = 9;
+}
+
+
+// Verify no warning for an extern struct object whose array may be
+// initialized to any number of elements.
+extern struct Ax axx;
+
+void gaxx (void)
+{
+  axx.a[0] = 0;
+  axx.a[3] = 3;
+  axx.a[9] = 9;
+}
+
+// Exercise zero-length array members.
+
+struct A0
+{
+  char n;
+  char a[0];                    // { dg-message "declared here" }
+};
+
+// Verify warning for a definition with no initializer.
+struct A0 a0_;
+
+void ga0_ (void)
+{
+  a0_.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the flexible array member.
+struct A0 a00 = { 0 };
+
+void ga00 (void)
+{
+  a00.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a00.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a00.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the flexible array member to empty.
+struct A0 a00_ = { 0, { } };
+
+void ga00_ (void)
+{
+  a00_.a[0] = 0;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a00_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a00_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// The following are rejected with
+//   error: too many initializers for 'char [0]'
+// A0 a01 = { 1, { 0 } };
+// A0 a02 = { 2, { 1, 0 } };
+
+
+// Verify no warning for an unknown struct object.
+void ga0p (struct A0 *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;
+  p->a[9] = 9;
+}
+
+
+// Verify warning for an extern struct object which (unlike a true
+// flexible array member) may not be initialized.
+extern struct A0 a0x;
+
+void ga0x (void)
+{
+  a0x.a[0] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0x.a[3] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a0x.a[9] = 0;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+
+// Exercise trailing one-element array members.
+
+struct A1
+{
+  char n;
+  char a[1];                    // { dg-message "declared here" }
+};
+
+// Verify warning for a definition with no initializer.
+struct A1 a1_;
+
+void ga1_ (void)
+{
+  a1_.a[0] = 0;
+  a1_.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a;
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the one-element array member.
+struct A1 a1__ = { 0 };
+
+void ga1__ (void)
+{
+  a1__.a[0] = 0;
+  a1__.a[1] = 1;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1__.a[2] = 2;                 // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 1 };
+  a.a[0] = 0;
+  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member to empty.
+struct A1 a1_0 = { 0, { } };
+
+void ga1_0_ (void)
+{
+  a1_0.a[0] = 0;
+  a1_0.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_0.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 1, { } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member.
+struct A1 a1_1 = { 0, { 1 } };
+
+void ga1_1 (void)
+{
+  a1_1.a[0] = 0;
+  a1_1.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1_1.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { 1 } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+
+// Verify no warning for an unknown struct object.
+void ga1p (struct A1 *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;
+  p->a[9] = 9;
+}
+
+
+// Verify warning for an extern struct object.  Similar to the zero-length
+// array case, a one-element trailing array can be initialized to at most
+// a single element.
+extern struct A1 a1x;
+
+void ga1x (void)
+{
+  a1x.a[0] = 0;
+  a1x.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1x.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+// Exercise interior one-element array members (verify they're not
+// treated as trailing.
+
+struct A1i
+{
+  char n;
+  char a[1];                    // { dg-message "declared here" }
+  char x;
+};
+
+// Verify warning for a definition with no initializer.
+struct A1i a1i_;
+
+void ga1i_ (void)
+{
+  a1i_.a[0] = 0;
+  a1i_.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1i a;
+  a.a[0] = 1;
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that doesn't
+// initialize the one-element array member.
+struct A1i a1i__ = { 0 };
+
+void ga1i__ (void)
+{
+  a1i__.a[0] = 0;
+  a1i__.a[1] = 1;                // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i__.a[2] = 2;                // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1i a = { 0 };
+  a.a[0] = 0;
+  a.a[1] = 1;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                    // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member to empty.
+struct A1 a1i_0 = { 0, { } };
+
+void ga1i_0_ (void)
+{
+  a1i_0.a[0] = 0;
+  a1i_0.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_0.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { } };
+  a.a[0] = 0;
+  a.a[1] = 1;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+// Verify warning for access to a definition with an initializer that
+// initializes the one-element array member.
+struct A1 a1i_1 = { 0, { 1 } };
+
+void ga1i_1 (void)
+{
+  a1i_1.a[0] = 0;
+  a1i_1.a[1] = 1;               // { dg-warning "\\\[-Wstringop-overflow" }
+  a1i_1.a[2] = 2;               // { dg-warning "\\\[-Wstringop-overflow" }
+
+  struct A1 a = { 0, { 1 } };
+  a.a[0] = 1;
+  a.a[1] = 2;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  a.a[2] = 3;                   // { dg-warning "\\\[-Wstringop-overflow" }
+  sink (&a);
+}
+
+
+// Verify no warning for an unknown struct object.
+void ga1ip (struct A1i *p)
+{
+  p->a[0] = 0;
+  p->a[3] = 3;                  // { dg-warning "\\\[-Wstringop-overflow" }
+  p->a[9] = 9;                  // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+
+// Verify no warning for an extern struct object.
+extern struct A1i a1ix;
+
+void ga1ix (void)
+{
+  a1ix.a[0] = 0;
+  a1ix.a[3] = 3;                 // { dg-warning "\\\[-Wstringop-overflow" }
+  a1ix.a[9] = 9;                 // { dg-warning "\\\[-Wstringop-overflow" }
+}