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]: 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);
 }


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