This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: backport fix for PR c/21911 to 4.0.x branch
- From: "Kaveh R. Ghazi" <ghazi at caipclassic dot rutgers dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Cc: mark at codesourcery dot com
- Date: Mon, 27 Jun 2005 22:10:10 -0400 (EDT)
- Subject: [PATCH]: backport fix for PR c/21911 to 4.0.x branch
I'd like to backport the fix for PR c/21911, a bug in sentinel
detection, to the 4.0.x branch. The 4.0 version of the patch is
identical to the one on mainline except we call warning(blah) instead
of warning(0, blah).
Bootrapped against 4.0 on x86_64-unknown-linux-gnu, no regressions.
Okay for 4.0?
Thanks,
--Kaveh
2005-06-27 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
PR c/21911
* c-common.c (check_function_sentinel): Pass in named argument
list, skip over named arguments before looking for a sentinel.
(check_function_arguments): Pass in named argument list.
* c-common.h (check_function_arguments): Likewise.
* c-typeck.c (build_function_call): Likewise.
cp:
* call.c (build_over_call): Pass in named argument list to
`check_function_arguments'.
* typeck.c (build_function_call): Likewise.
testsuite:
PR c/21911
* gcc.dg/format/sentinel-1.c: Update. Fix execl* calls.
diff -rup orig/egcc-4.0-CVS20050626/gcc/c-common.c egcc-4.0-CVS20050626/gcc/c-common.c
--- orig/egcc-4.0-CVS20050626/gcc/c-common.c 2005-06-06 19:12:48.000000000 -0400
+++ egcc-4.0-CVS20050626/gcc/c-common.c 2005-06-27 08:36:40.000000000 -0400
@@ -5084,14 +5084,21 @@ check_function_nonnull (tree attrs, tree
from the end) is a (pointer)0. */
static void
-check_function_sentinel (tree attrs, tree params)
+check_function_sentinel (tree attrs, tree params, tree typelist)
{
tree attr = lookup_attribute ("sentinel", attrs);
if (attr)
{
- if (!params)
- warning ("missing sentinel in function call");
+ /* Skip over the named arguments. */
+ while (typelist && params)
+ {
+ typelist = TREE_CHAIN (typelist);
+ params = TREE_CHAIN (params);
+ }
+
+ if (typelist || !params)
+ warning ("not enough variable arguments to fit a sentinel");
else
{
tree sentinel, end;
@@ -5114,7 +5121,7 @@ check_function_sentinel (tree attrs, tre
}
if (pos > 0)
{
- warning ("not enough arguments to fit a sentinel");
+ warning ("not enough variable arguments to fit a sentinel");
return;
}
@@ -5335,7 +5342,7 @@ handle_sentinel_attribute (tree *node, t
/* Check for valid arguments being passed to a function. */
void
-check_function_arguments (tree attrs, tree params)
+check_function_arguments (tree attrs, tree params, tree typelist)
{
/* Check for null being passed in a pointer argument that must be
non-null. We also need to do this if format checking is enabled. */
@@ -5348,7 +5355,7 @@ check_function_arguments (tree attrs, tr
if (warn_format)
{
check_function_format (attrs, params);
- check_function_sentinel (attrs, params);
+ check_function_sentinel (attrs, params, typelist);
}
}
diff -rup orig/egcc-4.0-CVS20050626/gcc/c-common.h egcc-4.0-CVS20050626/gcc/c-common.h
--- orig/egcc-4.0-CVS20050626/gcc/c-common.h 2005-05-01 06:52:53.000000000 -0400
+++ egcc-4.0-CVS20050626/gcc/c-common.h 2005-06-27 08:36:40.000000000 -0400
@@ -632,7 +632,7 @@ extern void finish_fname_decls (void);
extern const char *fname_as_string (int);
extern tree fname_decl (unsigned, tree);
-extern void check_function_arguments (tree, tree);
+extern void check_function_arguments (tree, tree, tree);
extern void check_function_arguments_recurse (void (*)
(void *, tree,
unsigned HOST_WIDE_INT),
diff -rup orig/egcc-4.0-CVS20050626/gcc/c-typeck.c egcc-4.0-CVS20050626/gcc/c-typeck.c
--- orig/egcc-4.0-CVS20050626/gcc/c-typeck.c 2005-06-06 19:12:48.000000000 -0400
+++ egcc-4.0-CVS20050626/gcc/c-typeck.c 2005-06-27 08:36:40.000000000 -0400
@@ -2061,7 +2061,8 @@ build_function_call (tree function, tree
/* Check that the arguments to the function are valid. */
- check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params);
+ check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params,
+ TYPE_ARG_TYPES (fntype));
result = build3 (CALL_EXPR, TREE_TYPE (fntype),
function, coerced_params, NULL_TREE);
diff -rup orig/egcc-4.0-CVS20050626/gcc/cp/call.c egcc-4.0-CVS20050626/gcc/cp/call.c
--- orig/egcc-4.0-CVS20050626/gcc/cp/call.c 2005-05-26 21:29:05.000000000 -0400
+++ egcc-4.0-CVS20050626/gcc/cp/call.c 2005-06-27 08:36:40.000000000 -0400
@@ -4790,7 +4790,7 @@ build_over_call (struct z_candidate *can
converted_args = nreverse (converted_args);
check_function_arguments (TYPE_ATTRIBUTES (TREE_TYPE (fn)),
- converted_args);
+ converted_args, TYPE_ARG_TYPES (TREE_TYPE (fn)));
/* Avoid actually calling copy constructors and copy assignment operators,
if possible. */
diff -rup orig/egcc-4.0-CVS20050626/gcc/cp/typeck.c egcc-4.0-CVS20050626/gcc/cp/typeck.c
--- orig/egcc-4.0-CVS20050626/gcc/cp/typeck.c 2005-06-03 21:47:56.000000000 -0400
+++ egcc-4.0-CVS20050626/gcc/cp/typeck.c 2005-06-27 08:36:40.000000000 -0400
@@ -2490,7 +2490,8 @@ build_function_call (tree function, tree
/* Check for errors in format strings and inappropriately
null parameters. */
- check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params);
+ check_function_arguments (TYPE_ATTRIBUTES (fntype), coerced_params,
+ TYPE_ARG_TYPES (fntype));
return build_cxx_call (function, coerced_params);
}
diff -rup orig/egcc-4.0-CVS20050626/gcc/testsuite/gcc.dg/format/sentinel-1.c egcc-4.0-CVS20050626/gcc/testsuite/gcc.dg/format/sentinel-1.c
--- orig/egcc-4.0-CVS20050626/gcc/testsuite/gcc.dg/format/sentinel-1.c 2004-09-04 22:55:28.000000000 -0400
+++ egcc-4.0-CVS20050626/gcc/testsuite/gcc.dg/format/sentinel-1.c 2005-06-27 08:36:40.000000000 -0400
@@ -27,40 +27,47 @@ extern void foo10 (const char *, ...) __
extern void bar(void)
{
- foo1 (); /* { dg-error "missing sentinel|too few arguments" "sentinel" } */
- foo1 ("a"); /* { dg-warning "missing sentinel" "sentinel" } */
+ foo1 (); /* { dg-error "not enough|too few arguments" "sentinel" } */
+ foo1 (NULL); /* { dg-warning "not enough" "sentinel" } */
+ foo1 ("a"); /* { dg-warning "not enough" "sentinel" } */
foo1 ("a", 1); /* { dg-warning "missing sentinel" "sentinel" } */
foo1 ("a", 0); /* { dg-warning "missing sentinel" "sentinel" } */
foo1 ("a", (void*)1); /* { dg-warning "missing sentinel" "sentinel" } */
foo1 ("a", NULL, 1); /* { dg-warning "missing sentinel" "sentinel" } */
foo1 ("a", NULL);
+ foo5 (NULL); /* { dg-warning "not enough" "sentinel" } */
+ foo5 (NULL, 1); /* { dg-warning "not enough" "sentinel" } */
+ foo5 ("a", NULL); /* { dg-warning "not enough" "sentinel" } */
+ foo5 ("a", NULL, 1);
foo5 ("a", 1, 2, 3, NULL); /* { dg-warning "missing sentinel" "sentinel" } */
foo5 ("a", 1, 2, NULL, 3);
foo5 ("a", 1, NULL, 2, 3); /* { dg-warning "missing sentinel" "sentinel" } */
foo5 ("a", NULL, 1, 2, 3); /* { dg-warning "missing sentinel" "sentinel" } */
foo5 ("a", 0, 1, 2, 3); /* { dg-warning "missing sentinel" "sentinel" } */
- foo6 ("a", 1, NULL); /* { dg-warning "not enough arguments" "sentinel" } */
- foo6 ("a", 1, NULL, 2); /* { dg-warning "not enough arguments" "sentinel" } */
- foo6 ("a", 1, NULL, 2, 3); /* { dg-warning "not enough arguments" "sentinel" } */
- foo6 ("a", NULL, 1, 2, 3); /* { dg-warning "not enough arguments" "sentinel" } */
- foo6 ("a", NULL, 1, 2, 3, 4); /* { dg-warning "missing sentinel" "sentinel" } */
+ foo6 ("a", 1, NULL); /* { dg-warning "not enough" "sentinel" } */
+ foo6 ("a", 1, NULL, 2); /* { dg-warning "not enough" "sentinel" } */
+ foo6 ("a", 1, NULL, 2, 3); /* { dg-warning "not enough" "sentinel" } */
+ foo6 ("a", NULL, 1, 2, 3); /* { dg-warning "not enough" "sentinel" } */
+ foo6 ("a", NULL, 1, 2, 3, 4); /* { dg-warning "not enough" "sentinel" } */
+ foo6 (NULL, 1, 2, 3, 4, 5); /* { dg-warning "not enough" "sentinel" } */
foo6 ("a", NULL, 1, 2, 3, 4, 5);
+ foo6 ("a", 0, NULL, 1, 2, 3, 4, 5);
foo6 ("a", 0, 1, 2, 3, 4, 5); /* { dg-warning "missing sentinel" "sentinel" } */
foo6 ("a", NULL, 1, 2, 3, 4, 5, 6); /* { dg-warning "missing sentinel" "sentinel" } */
foo7 ("a", 1, 2, 3, NULL);
- execl ("/bin/ls", "-aFC"); /* { dg-warning "missing sentinel" "sentinel" } */
- execl ("/bin/ls", "-aFC", 0); /* { dg-warning "missing sentinel" "sentinel" } */
- execl ("/bin/ls", "-aFC", NULL);
-
- execlp ("ls", "-aFC"); /* { dg-warning "missing sentinel" "sentinel" } */
- execlp ("ls", "-aFC", 0); /* { dg-warning "missing sentinel" "sentinel" } */
- execlp ("ls", "-aFC", NULL);
-
- execle ("ls", "-aFC", ".", envp); /* { dg-warning "missing sentinel" "sentinel" } */
- execle ("ls", "-aFC", ".", 0, envp); /* { dg-warning "missing sentinel" "sentinel" } */
- execle ("ls", "-aFC", ".", NULL, envp);
+ execl ("/bin/ls", "/bin/ls", "-aFC"); /* { dg-warning "missing sentinel" "sentinel" } */
+ execl ("/bin/ls", "/bin/ls", "-aFC", 0); /* { dg-warning "missing sentinel" "sentinel" } */
+ execl ("/bin/ls", "/bin/ls", "-aFC", NULL);
+
+ execlp ("ls", "ls", "-aFC"); /* { dg-warning "missing sentinel" "sentinel" } */
+ execlp ("ls", "ls", "-aFC", 0); /* { dg-warning "missing sentinel" "sentinel" } */
+ execlp ("ls", "ls", "-aFC", NULL);
+
+ execle ("ls", "ls", "-aFC", ".", envp); /* { dg-warning "missing sentinel" "sentinel" } */
+ execle ("ls", "ls", "-aFC", ".", 0, envp); /* { dg-warning "missing sentinel" "sentinel" } */
+ execle ("ls", "ls", "-aFC", ".", NULL, envp);
}