PR c/81117 - Improve buffer overflow checking in strncpy - part 2
authorMartin Sebor <msebor@redhat.com>
Mon, 14 Aug 2017 20:21:44 +0000 (20:21 +0000)
committerMartin Sebor <msebor@gcc.gnu.org>
Mon, 14 Aug 2017 20:21:44 +0000 (14:21 -0600)
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
gcc/c-family/ChangeLog
gcc/c-family/c-attribs.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog

index 9697dd9017024b2d2684805aeb5313718fd5b4b3..5902989dcd770e987275e96529a6910e583253db 100644 (file)
@@ -1,3 +1,8 @@
+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
index 155383de773d2cc0a52d3f855ac13c006f3bd49f..a769350d69e7be9b25701938be0f2bf406945aa6 100644 (file)
@@ -1,3 +1,9 @@
+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
index a40b0649ca3d7006adb8fe8875f282a8a2850a9f..ad2289cd91f68837cfece28b33ecdd98b8a6e981 100644 (file)
@@ -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.  */
 
index b253cccfa62ab588363768bb809c78908f22f64f..22062e65a894828747ca671d98a8a51e085e638f 100644 (file)
@@ -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
index 2bd4fad515323138957bc83e1777844b429e98e7..ddbafae0fe3a54dd9572e741af23039b6af6088f 100644 (file)
@@ -1,3 +1,8 @@
+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