aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2017-08-14 20:21:44 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2017-08-14 14:21:44 -0600
commit27be025d191e308b706cdd7f1f90f0fe490f9a2c (patch)
treea055a2735dded9ec61ad2030b010e8a12e6dbd78
parentda67acb9b37cf139da014f5bc11e2dbf25a7d597 (diff)
downloadgcc-27be025d191e308b706cdd7f1f90f0fe490f9a2c.zip
gcc-27be025d191e308b706cdd7f1f90f0fe490f9a2c.tar.gz
gcc-27be025d191e308b706cdd7f1f90f0fe490f9a2c.tar.bz2
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
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-attribs.c45
-rw-r--r--gcc/doc/extend.texi24
-rw-r--r--gcc/testsuite/ChangeLog5
5 files changed, 85 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9697dd9..5902989 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,11 @@
2017-08-14 Martin Sebor <msebor@redhat.com>
PR c/81117
+ * doc/extend.texi (attribute nonstring): Document new attribute.
+
+2017-08-14 Martin Sebor <msebor@redhat.com>
+
+ PR c/81117
* tree-diagnostic.c (default_tree_printer): Handle %G.
* gimple-pretty-print.h (percent_G_format): Declare new function.
* gimple-pretty-print.c (percent_G_format): Define.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 155383d..a769350 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,6 +1,12 @@
2017-08-14 Martin Sebor <msebor@redhat.com>
PR c/81117
+ * c-attribs.c (c_common_attribute_table): Add nonstring entry.
+ (handle_nonstring_attribute): New function.
+
+2017-08-14 Martin Sebor <msebor@redhat.com>
+
+ PR c/81117
* c-format.h (T89_G): New macro.
* c-format.c (local_gcall_ptr_node): New variable.
(init_dynamic_diag_info): Initialize it.
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index a40b064..ad2289c 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 b253ccc..22062e6 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 2bd4fad..ddbafae 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,11 @@
2017-08-14 Martin Sebor <msebor@redhat.com>
PR c/81117
+ * c-c++-common/attr-nonstring-1.c: New test.
+
+2017-08-14 Martin Sebor <msebor@redhat.com>
+
+ PR c/81117
* gcc.dg/format/gcc_diag-10.c: Exercise %G.
2017-08-14 David Edelsohn <dje.gcc@gmail.com>