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.

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).

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)

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");
        }
     }

Reply via email to