From 27be025d191e308b706cdd7f1f90f0fe490f9a2c Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 14 Aug 2017 20:21:44 +0000 Subject: [PATCH] PR c/81117 - Improve buffer overflow checking in strncpy - part 2 gcc/ChangeLog: PR c/81117 * doc/extend.texi (attribute nonstring): Document new attribute. gcc/c-family/ChangeLog: PR c/81117 * c-attribs.c (c_common_attribute_table): Add nonstring entry. (handle_nonstring_attribute): New function. gcc/testsuite/ChangeLog: PR c/81117 * c-c++-common/attr-nonstring-1.c: New test. From-SVN: r251100 --- gcc/ChangeLog | 5 +++++ gcc/c-family/ChangeLog | 6 ++++++ gcc/c-family/c-attribs.c | 45 ++++++++++++++++++++++++++++++++++++++++ gcc/doc/extend.texi | 24 +++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 +++++ 5 files changed, 85 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9697dd90170..5902989dcd7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-08-14 Martin Sebor + + PR c/81117 + * doc/extend.texi (attribute nonstring): Document new attribute. + 2017-08-14 Martin Sebor PR c/81117 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 155383de773..a769350d69e 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2017-08-14 Martin Sebor + + PR c/81117 + * c-attribs.c (c_common_attribute_table): Add nonstring entry. + (handle_nonstring_attribute): New function. + 2017-08-14 Martin Sebor PR c/81117 diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index a40b0649ca3..ad2289cd91f 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -116,6 +116,7 @@ static tree handle_deprecated_attribute (tree *, tree, tree, int, static tree handle_vector_size_attribute (tree *, tree, tree, int, bool *); static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); +static tree handle_nonstring_attribute (tree *, tree, tree, int, bool *); static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); static tree handle_cleanup_attribute (tree *, tree, tree, int, bool *); static tree handle_warn_unused_result_attribute (tree *, tree, tree, int, @@ -270,6 +271,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_tls_model_attribute, false }, { "nonnull", 0, -1, false, true, true, handle_nonnull_attribute, false }, + { "nonstring", 0, 0, true, false, false, + handle_nonstring_attribute, false }, { "nothrow", 0, 0, true, false, false, handle_nothrow_attribute, false }, { "may_alias", 0, 0, false, true, false, NULL, false }, @@ -2970,6 +2973,48 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), return NULL_TREE; } +/* Handle the "nonstring" variable attribute. */ + +static tree +handle_nonstring_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + gcc_assert (!args); + tree_code code = TREE_CODE (*node); + + if (VAR_P (*node) + || code == FIELD_DECL + || code == PARM_DECL) + { + tree type = TREE_TYPE (*node); + + if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) + { + tree eltype = TREE_TYPE (type); + if (eltype == char_type_node) + return NULL_TREE; + } + + warning (OPT_Wattributes, + "%qE attribute ignored on objects of type %qT", + name, type); + *no_add_attrs = true; + return NULL_TREE; + } + + if (code == FUNCTION_DECL) + warning (OPT_Wattributes, + "%qE attribute does not apply to functions", name); + else if (code == TYPE_DECL) + warning (OPT_Wattributes, + "%qE attribute does not apply to types", name); + else + warning (OPT_Wattributes, "%qE attribute ignored", name); + + *no_add_attrs = true; + return NULL_TREE; +} + /* Handle a "nothrow" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index b253cccfa62..22062e65a89 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5835,6 +5835,30 @@ The @code{deprecated} attribute can also be used for functions and types (@pxref{Common Function Attributes}, @pxref{Common Type Attributes}). +@item nonstring (@var{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 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 call below because it may +truncate the copy without appending the terminating NUL character. Using +the attribute makes it possible to suppress the warning. + +@smallexample +struct Data +@{ + char name [32] __attribute__ ((nonstring)); +@}; +void f (struct Data *pd, const char *s) +@{ + strncpy (pd->name, s, sizeof pd->name); + @dots{} +@} +@end smallexample + @item mode (@var{mode}) @cindex @code{mode} variable attribute This attribute specifies the data type for the declaration---whichever diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2bd4fad5153..ddbafae0fe3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-08-14 Martin Sebor + + PR c/81117 + * c-c++-common/attr-nonstring-1.c: New test. + 2017-08-14 Martin Sebor PR c/81117 -- 2.30.2