From: Martin Sebor Date: Tue, 13 Mar 2018 15:33:16 +0000 (+0000) Subject: PR tree-optimization/84725 - enable attribute nonstring for all narrow character... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f99309b288733c88d5369af11a6c11dcc307ff49;p=gcc.git PR tree-optimization/84725 - enable attribute nonstring for all narrow character types 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 --- diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 259445365c4..10c70476d91 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2018-03-13 Martin Sebor + + 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 PR tree-optimization/83456 diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index cebc0b2884d..e0630885cca 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -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; } diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 1379502ebbb..58048adf055 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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}, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cee70dc0bc9..8f15d5fc6aa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-03-13 Martin Sebor + + 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 * 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 index 00000000000..c4ad4d6dafc --- /dev/null +++ b/gcc/testsuite/c-c++-common/Wstringop-truncation-4.c @@ -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 index 00000000000..f9b4fd92732 --- /dev/null +++ b/gcc/testsuite/c-c++-common/attr-nonstring-5.c @@ -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" } */