This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Extend the `sentinel' attribute
- From: ludo at gnu dot org (Ludovic Courtès)
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 16 Apr 2008 18:01:36 +0200
- Subject: [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