PR tree-optimization/84725 - enable attribute nonstring for all narrow character...
authorMartin Sebor <msebor@redhat.com>
Tue, 13 Mar 2018 15:33:16 +0000 (15:33 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Tue, 13 Mar 2018 15:33:16 +0000 (09:33 -0600)
gcc/c-family/ChangeLog:

PR tree-optimization/84725
* c-attribs.c (handle_nonstring_attribute): Allow attribute nonstring
with all three narrow character types, including their qualified forms.

gcc/testsuite/ChangeLog:

PR tree-optimization/84725
* c-c++-common/Wstringop-truncation-4.c: New test.
* c-c++-common/attr-nonstring-5.c: New test.

From-SVN: r258492

gcc/c-family/ChangeLog
gcc/c-family/c-attribs.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/Wstringop-truncation-4.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/attr-nonstring-5.c [new file with mode: 0644]

index 259445365c4232171407cede8bb1a0d292e35482..10c70476d913de47416b92f41fd7459a82540cb9 100644 (file)
@@ -1,3 +1,9 @@
+2018-03-13  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/84725
+       * c-attribs.c (handle_nonstring_attribute): Allow attribute nonstring
+       with all three narrow character types, including their qualified forms.
+
 2018-03-12  Martin Sebor  <msebor@redhat.com>
 
        PR tree-optimization/83456
index cebc0b2884d240e29c39ade20164e1c5fa494ebb..e0630885cca3610d6cc5453819355425c175e9e1 100644 (file)
@@ -3194,8 +3194,13 @@ handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args),
 
       if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
        {
+         /* Accept the attribute on arrays and pointers to all three
+            narrow character types.  */
          tree eltype = TREE_TYPE (type);
-         if (eltype == char_type_node)
+         eltype = TYPE_MAIN_VARIANT (eltype);
+         if (eltype == char_type_node
+             || eltype == signed_char_type_node
+             || eltype == unsigned_char_type_node)
            return NULL_TREE;
        }
 
index 1379502ebbbb45823e123842a61c222914ed713b..58048adf05514521948c8dc4ca912f54ea07a131 100644 (file)
@@ -6080,17 +6080,17 @@ types (@pxref{Common Function Attributes},
 @item nonstring
 @cindex @code{nonstring} variable attribute
 The @code{nonstring} variable attribute specifies that an object or member
-declaration with type array of @code{char} or pointer to @code{char} is
-intended to store character arrays that do not necessarily contain
-a terminating @code{NUL} character.  This is useful in detecting uses
-of such arrays or pointers with functions that expect NUL-terminated
-strings, and to avoid warnings when such an array or pointer is used
-as an argument to a bounded string manipulation function such as
-@code{strncpy}.  For example, without the attribute, GCC will issue
-a warning for the @code{strncpy} call below because it may truncate
-the copy without appending the terminating @code{NUL} character.  Using
-the attribute makes it possible to suppress the warning.  However, when
-the array is declared with the attribute the call to @code{strlen} is
+declaration with type array of @code{char}, @code{signed char}, or
+@code{unsigned char}, or pointer to such a type is intended to store
+character arrays that do not necessarily contain a terminating @code{NUL}.
+This is useful in detecting uses of such arrays or pointers with functions
+that expect @code{NUL}-terminated strings, and to avoid warnings when such
+an array or pointer is used as an argument to a bounded string manipulation
+function such as @code{strncpy}.  For example, without the attribute, GCC
+will issue a warning for the @code{strncpy} call below because it may
+truncate the copy without appending the terminating @code{NUL} character.
+Using the attribute makes it possible to suppress the warning.  However,
+when the array is declared with the attribute the call to @code{strlen} is
 diagnosed because when the array doesn't contain a @code{NUL}-terminated
 string the call is undefined.  To copy, compare, of search non-string
 character arrays use the @code{memcpy}, @code{memcmp}, @code{memchr},
index cee70dc0bc9b8f567c7bdfdfcbdb90c5907199d0..8f15d5fc6aad9725375ed978ff2cc545b489671d 100644 (file)
@@ -1,3 +1,9 @@
+2018-03-13  Martin Sebor  <msebor@redhat.com>
+
+       PR tree-optimization/84725
+       * c-c++-common/Wstringop-truncation-4.c: New test.
+       * c-c++-common/attr-nonstring-5.c: New test.
+
 2018-03-13  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * gcc.target/aarch64/sve/unpack_fcvt_signed_1.c: Expect zips rather
diff --git a/gcc/testsuite/c-c++-common/Wstringop-truncation-4.c b/gcc/testsuite/c-c++-common/Wstringop-truncation-4.c
new file mode 100644 (file)
index 0000000..c4ad4d6
--- /dev/null
@@ -0,0 +1,127 @@
+/* PR middle-end/84725 - enable attribute nonstring for all narrow character
+   types
+   Verify that -Wstringop-truncation is issued for uses of arrays and
+   pointers to qualified forms of characters of all three types.
+   { dg-do compile }
+   { dg-options "-O2 -Wall -Wstringop-truncation" } */
+
+#if __cplusplus
+extern "C"
+#endif
+char* strncpy (char*, const char*, __SIZE_TYPE__);
+
+#define S "1234"
+
+struct Arrays
+{
+  char a[4];
+  signed char b[4];
+  unsigned char c[4];
+};
+
+void test_arrays (struct Arrays *p, const char *s)
+{
+  strncpy (p->a, s, sizeof p->a);           /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->b, s, sizeof p->b);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->c, s, sizeof p->c);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+struct Pointers
+{
+  char *p;
+  signed char *q;
+  unsigned char *r;
+};
+
+void test_pointers (struct Pointers *p)
+{
+  strncpy (p->p, S, sizeof S - 1);          /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->q, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->r, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+struct ConstArrays
+{
+  const char a[4];
+  const signed char b[4];
+  const unsigned char c[4];
+};
+
+void test_const_arrays (struct ConstArrays *p, const char *s)
+{
+  strncpy ((char*)p->a, s, sizeof p->a);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->b, s, sizeof p->b);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->c, s, sizeof p->c);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+struct ConstPointers
+{
+  const char *p;
+  const signed char *q;
+  const unsigned char *r;
+};
+
+void test_const_pointers (struct ConstPointers *p)
+{
+  strncpy ((char*)p->p, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->q, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->r, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+struct VolatileArrays
+{
+  volatile char a[4];
+  volatile signed char b[4];
+  volatile unsigned char c[4];
+};
+
+void test_volatile_arrays (struct VolatileArrays *p, const char *s)
+{
+  strncpy ((char*)p->a, s, sizeof p->a);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->b, s, sizeof p->b);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->c, s, sizeof p->c);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+struct VolatilePointers
+{
+  volatile char *p;
+  volatile signed char *q;
+  volatile unsigned char *r;
+};
+
+void test_volatile_pointers (struct VolatilePointers *p)
+{
+  strncpy ((char*)p->p, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->q, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->r, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+struct ConstVolatileArrays
+{
+  const volatile char a[4];
+  const volatile signed char b[4];
+  const volatile unsigned char c[4];
+};
+
+void test_const_volatile_arrays (struct ConstVolatileArrays *p, const char *s)
+{
+  strncpy ((char*)p->a, s, sizeof p->a);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->b, s, sizeof p->b);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->c, s, sizeof p->c);    /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+struct ConstVolatilePointers
+{
+  const volatile char *p;
+  const volatile signed char *q;
+  const volatile unsigned char *r;
+};
+
+void test_const_volatile_pointers (struct ConstVolatilePointers *p)
+{
+  strncpy ((char*)p->p, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->q, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+  strncpy ((char*)p->r, S, sizeof S - 1);   /* { dg-warning "\\\[-Wstringop-truncation" } */
+}
+
+/* { dg-prune-output "-Wdiscarded-qualifiers" } */
diff --git a/gcc/testsuite/c-c++-common/attr-nonstring-5.c b/gcc/testsuite/c-c++-common/attr-nonstring-5.c
new file mode 100644 (file)
index 0000000..f9b4fd9
--- /dev/null
@@ -0,0 +1,131 @@
+/* PR middle-end/84725 - enable attribute nonstring for all narrow character
+   types
+   Verify that using attribute nonstring with all three narrow character
+   types is accepted and using arrays and pointers to characters of all
+   three types (including their qualified forms) declared with the
+   attributes doesn't trigger -Wstringop-truncation warnings.
+   { dg-do compile }
+   { dg-options "-O -Wall -Wstringop-truncation" } */
+
+#if __cplusplus
+extern "C"
+#endif
+char* strncpy (char*, const char*, __SIZE_TYPE__);
+
+#define NONSTR __attribute__ ((nonstring))
+
+#define S "1234"
+
+struct Arrays
+{
+  char NONSTR a[4];
+  signed char NONSTR b[4];
+  unsigned char NONSTR c[4];
+};
+
+void test_arrays (struct Arrays *p, const char *s)
+{
+  strncpy (p->a, s, sizeof p->a);
+  strncpy ((char*)p->b, s, sizeof p->b);
+  strncpy ((char*)p->c, s, sizeof p->c);
+}
+
+struct Pointers
+{
+  char NONSTR *p;
+  signed char NONSTR *q;
+  unsigned char NONSTR *r;
+};
+
+void test_pointers (struct Pointers *p)
+{
+  strncpy (p->p, S, sizeof S - 1);
+  strncpy ((char*)p->q, S, sizeof S - 1);
+  strncpy ((char*)p->r, S, sizeof S - 1);
+}
+
+struct ConstArrays
+{
+  const char NONSTR a[4];
+  const signed char NONSTR b[4];
+  const unsigned char NONSTR c[4];
+};
+
+void test_const_arrays (struct ConstArrays *p, const char *s)
+{
+  strncpy ((char*)p->a, s, sizeof p->a);
+  strncpy ((char*)p->b, s, sizeof p->b);
+  strncpy ((char*)p->c, s, sizeof p->c);
+}
+
+struct ConstPointers
+{
+  const char NONSTR *p;
+  const signed char NONSTR *q;
+  const unsigned char NONSTR *r;
+};
+
+void test_const_pointers (struct ConstPointers *p)
+{
+  strncpy ((char*)p->p, S, sizeof S - 1);
+  strncpy ((char*)p->q, S, sizeof S - 1);
+  strncpy ((char*)p->r, S, sizeof S - 1);
+}
+
+struct VolatileArrays
+{
+  volatile char NONSTR a[4];
+  volatile signed char NONSTR b[4];
+  volatile unsigned char NONSTR c[4];
+};
+
+void test_volatile_arrays (struct VolatileArrays *p, const char *s)
+{
+  strncpy ((char*)p->a, s, sizeof p->a);
+  strncpy ((char*)p->b, s, sizeof p->b);
+  strncpy ((char*)p->c, s, sizeof p->c);
+}
+
+struct VolatilePointers
+{
+  volatile char NONSTR *p;
+  volatile signed char NONSTR *q;
+  volatile unsigned char NONSTR *r;
+};
+
+void test_volatile_pointers (struct VolatilePointers *p)
+{
+  strncpy ((char*)p->p, S, sizeof S - 1);
+  strncpy ((char*)p->q, S, sizeof S - 1);
+  strncpy ((char*)p->r, S, sizeof S - 1);
+}
+
+struct ConstVolatileArrays
+{
+  const volatile char NONSTR a[4];
+  const volatile signed char NONSTR b[4];
+  const volatile unsigned char NONSTR c[4];
+};
+
+void test_const_volatile_arrays (struct ConstVolatileArrays *p, const char *s)
+{
+  strncpy ((char*)p->a, s, sizeof p->a);
+  strncpy ((char*)p->b, s, sizeof p->b);
+  strncpy ((char*)p->c, s, sizeof p->c);
+}
+
+struct ConstVolatilePointers
+{
+  const volatile char NONSTR *p;
+  const volatile signed char NONSTR *q;
+  const volatile unsigned char NONSTR *r;
+};
+
+void test_const_volatile_pointers (struct ConstVolatilePointers *p)
+{
+  strncpy ((char*)p->p, S, sizeof S - 1);
+  strncpy ((char*)p->q, S, sizeof S - 1);
+  strncpy ((char*)p->r, S, sizeof S - 1);
+}
+
+/* { dg-prune-output "-Wdiscarded-qualifiers" } */