Commit f99309b2 by Martin Sebor Committed by Martin Sebor

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
parent 9bfb28ed
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
......
......@@ -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;
}
......
......@@ -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},
......
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
......
/* 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" } */
/* 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" } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment