This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Extend the `sentinel' attribute


Hello,

The attached patch adds a second optional parameter to the `sentinel'
attribute, allowing the expected sentinel value to be specified.  IOW,
it allows `sentinel' to be used for non-NULL values and addresses bug
#28319:

  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28319

Does that seem like a reasonable change?

In addition, it would be nice to no limit sentinel values to pointer
types but this would be an incompatible change.  What do you think?

Thanks,
Ludovic.

PS: I have not (yet) assigned copyright to the FSF, but maybe the change
    is trivial enough that it's not necessary?


2008-04-16  Ludovic Courtès  <ludo@gnu.org>

	PR28319
        * c-common.c (c_common_attribute_table): Set max argument count
        to 2.
        (check_function_sentinel): Check SENTINEL against the
        user-provided value rather than against zero.
        (handle_sentinel_attribute): Validate second optional argument.
        * doc/extend.texi (Function Attributes): Document `sentinel'
        change.

diff --git a/gcc/c-common.c b/gcc/c-common.c
index 2bc7434..14eb688 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -647,7 +647,7 @@ const struct attribute_spec c_common_attribute_table[] =
 			      handle_cleanup_attribute },
   { "warn_unused_result",     0, 0, false, true, true,
 			      handle_warn_unused_result_attribute },
-  { "sentinel",               0, 1, false, true, true,
+  { "sentinel",               0, 2, false, true, true,
 			      handle_sentinel_attribute },
   /* For internal use (marking of builtins) only.  The name contains space
      to prevent its usage in source code.  */
@@ -6214,7 +6214,7 @@ check_function_sentinel (tree attrs, int nargs, tree *argarray, tree typelist)
     {
       int len = 0;
       int pos = 0;
-      tree sentinel;
+      tree value, sentinel;
 
       /* Skip over the named arguments.  */
       while (typelist && len < nargs)
@@ -6227,6 +6227,14 @@ check_function_sentinel (tree attrs, int nargs, tree *argarray, tree typelist)
 	{
 	  tree p = TREE_VALUE (TREE_VALUE (attr));
 	  pos = TREE_INT_CST_LOW (p);
+
+	  value = TREE_CHAIN (TREE_VALUE (attr));
+	  if (value)
+	    /* Use the user-provided sentinel value.  */
+	    value = TREE_VALUE (value);
+	  else
+	    /* Default to zero.  */
+	    value = integer_zero_node;
 	}
 
       /* The sentinel must be one of the varargs, i.e.
@@ -6241,7 +6249,7 @@ check_function_sentinel (tree attrs, int nargs, tree *argarray, tree typelist)
       /* Validate the sentinel.  */
       sentinel = argarray[nargs - 1 - pos];
       if ((!POINTER_TYPE_P (TREE_TYPE (sentinel))
-	   || !integer_zerop (sentinel))
+	   || !tree_int_cst_equal (sentinel, value))
 	  /* Although __null (in C++) is only an integer we allow it
 	     nevertheless, as we are guaranteed that it's exactly
 	     as wide as a pointer, and we don't want to force
@@ -6434,6 +6442,21 @@ handle_sentinel_attribute (tree *node, tree name, tree args,
 		       "requested position is less than zero");
 	      *no_add_attrs = true;
 	    }
+
+	  args = TREE_CHAIN (args);
+	  if (args)
+	    {
+	      /* Check the user-provided sentinel value.  */
+	      tree value = TREE_VALUE (args);
+
+	      if (TREE_CODE (value) != INTEGER_CST)
+		{
+		  warning (OPT_Wattributes,
+			   "requested sentinel value is not "
+			   "an integer constant");
+		  *no_add_attrs = true;
+		}
+	    }
 	}
     }
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 5dfbbcf..f1f684b 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2758,10 +2758,15 @@ last parameter of the function call.  If an optional integer position
 argument P is supplied to the attribute, the sentinel must be located at
 position P counting backwards from the end of the argument list.
 
+Optionally, a second integer constant can be passed that determines the
+expected sentinel value.
+
 @smallexample
 __attribute__ ((sentinel))
 is equivalent to
 __attribute__ ((sentinel(0)))
+and is equivalent to
+__attribute__ ((sentinel(0, 0)))
 @end smallexample
 
 The attribute is automatically set with a position of 0 for the built-in

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]