On Sat, Apr 02, 2011 at 11:13:05AM +0000, Miod Vallat wrote:
> The -Wsentinel warning is supposed to complain when the last argument in
> a call to a function which has __attribute__((sentinel)) is not a NULL
> pointer.
>
> However, the current implementation of the check in gcc 3 and gcc 4 will
> warn if the last argument is not explicitely declared as a pointer type,
> i.e.
> execl(foo, bar, (const char *)NULL)
> will not warn, but
> execl(foo, bar, NULL)
> will cause a false warning, because NULL is defined as 0L for non-C++
> code.
Heh, had the same problem with the new binutils. This will remove some
of the MI modifications I've made that fixed compiling with -Werror.
> The following diff relaxes the check to let it accept either a pointer
> or an integer type of the same width as a pointer (i.e. on a 64 bit
> platform, using 0L will compile silently, but using 0 will).
I think you meant: but using 0 will not.
>
> Ok? (note that this has only been tested on gcc 4, the gcc 3 version is
> similar but has not even been checked to compile yet)
This reads okay to me.
>
> Index: gnu/gcc/gcc/c-common.c
> ===================================================================
> RCS file: /cvs/src/gnu/gcc/gcc/c-common.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 c-common.c
> --- gnu/gcc/gcc/c-common.c 12 May 2010 13:35:20 -0000 1.3
> +++ gnu/gcc/gcc/c-common.c 2 Apr 2011 11:04:49 -0000
> @@ -5498,15 +5498,17 @@ check_function_sentinel (tree attrs, tre
> }
>
> /* Validate the sentinel. */
> - if ((!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel)))
> - || !integer_zerop (TREE_VALUE (sentinel)))
> + sentinel = TREE_VALUE (sentinel);
> + if ((!(POINTER_TYPE_P (TREE_TYPE (sentinel))
> + || (TREE_CODE (sentinel) == INTEGER_CST
> + && TYPE_PRECISION (TREE_TYPE (sentinel)) == POINTER_SIZE))
> + || !integer_zerop (sentinel))
> /* 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
> users to cast the NULL they have written there.
> We warn with -Wstrict-null-sentinel, though. */
> - && (warn_strict_null_sentinel
> - || null_node != TREE_VALUE (sentinel)))
> + && (warn_strict_null_sentinel || null_node != sentinel))
> warning (OPT_Wformat, "missing sentinel in function call");
> }
> }
> Index: gnu/usr.bin/gcc/gcc/c-common.c
> ===================================================================
> RCS file: /cvs/src/gnu/usr.bin/gcc/gcc/c-common.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 c-common.c
> --- gnu/usr.bin/gcc/gcc/c-common.c 16 Oct 2009 12:22:07 -0000 1.6
> +++ gnu/usr.bin/gcc/gcc/c-common.c 2 Apr 2011 11:04:50 -0000
> @@ -6502,8 +6502,11 @@ check_function_sentinel (attrs, params)
> }
>
> /* Validate the sentinel. */
> - if (!POINTER_TYPE_P (TREE_TYPE (TREE_VALUE (sentinel)))
> - || !integer_zerop (TREE_VALUE (sentinel)))
> + sentinel = TREE_VALUE (sentinel);
> + if (!(POINTER_TYPE_P (TREE_TYPE (sentinel))
> + || (TREE_CODE (sentinel) == INTEGER_CST
> + && TYPE_PRECISION (TREE_TYPE (sentinel)) == POINTER_SIZE))
> + || !integer_zerop (sentinel))
> warning ("missing sentinel in function call");
> }
> }