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]

Fix PR66208


This is a relatively straightforward PR where we should mention a macro expansion in a warning message. The patch below implements the suggestion by Marek to pass a location down from build_function_call_vec. Ok if tests pass on x86_64-linux?

One question I have is about -Wformat, which is dealt with in the same area. We do get a mention of the macro expansion, but in a different style:

/* { dg-do compile } */
/* { dg-options "-Wformat" } */

int foox (const char *, ...) __attribute__ ((format (printf, 1, 2)));

#define foo(p, x) foox (p, x)
#define foo3(p, x, y) foox (p, x, y)

void
bar (unsigned int x)
{
  foo ("%x", "fish");
  foo3 ("%x", 3, "fish");
}

macroloc2.c: In function âbarâ:
macroloc2.c:12:8: warning: format â%xâ expects argument of type âunsigned intâ, but argument 2 has type âchar *â [-Wformat=]
   foo ("%x", "fish");
        ^
macroloc2.c:6:25: note: in definition of macro âfooâ
 #define foo(p, x) foox (p, x)
                         ^
macroloc2.c:13:9: warning: too many arguments for format [-Wformat-extra-args]
   foo3 ("%x", 3, "fish");
         ^
macroloc2.c:7:29: note: in definition of macro âfoo3â
 #define foo3(p, x, y) foox (p, x, y)
                             ^

Is this what we're looking for in terms of output?


Bernd
	PR c/66208
	* c-common.c (check_function_nonnull): Remove unnecessary declaration.
	Add new arg loc and pass it down as context.
	(check_nonnull_arg): Don't mark ctx arg as unused. Use it as a pointer
	to the location to use for the warning.
	(check_function_arguments): New arg loc.  All callers changed.  Pass
	it to check_function_nonnull.
	* c-common.h (check_function_arguments): Adjust declaration.

testsuite/
	PR c/66208
	* c-c++-common/pr66208.c: New file.

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 369574f..6074d14 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -395,7 +395,6 @@ static tree handle_bnd_variable_size_attribute (tree *, tree, tree, int, bool *)
 static tree handle_bnd_legacy (tree *, tree, tree, int, bool *);
 static tree handle_bnd_instrument (tree *, tree, tree, int, bool *);
 
-static void check_function_nonnull (tree, int, tree *);
 static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
 static bool nonnull_check_p (tree, unsigned HOST_WIDE_INT);
 static bool get_nonnull_operand (tree, unsigned HOST_WIDE_INT *);
@@ -9611,11 +9610,10 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
 
 /* Check the argument list of a function call for null in argument slots
    that are marked as requiring a non-null pointer argument.  The NARGS
-   arguments are passed in the array ARGARRAY.
-*/
+   arguments are passed in the array ARGARRAY.  */
 
 static void
-check_function_nonnull (tree attrs, int nargs, tree *argarray)
+check_function_nonnull (location_t loc, tree attrs, int nargs, tree *argarray)
 {
   tree a;
   int i;
@@ -9635,7 +9633,7 @@ check_function_nonnull (tree attrs, int nargs, tree *argarray)
 
   if (a != NULL_TREE)
     for (i = 0; i < nargs; i++)
-      check_function_arguments_recurse (check_nonnull_arg, NULL, argarray[i],
+      check_function_arguments_recurse (check_nonnull_arg, &loc, argarray[i],
 					i + 1);
   else
     {
@@ -9651,7 +9649,7 @@ check_function_nonnull (tree attrs, int nargs, tree *argarray)
 	    }
 
 	  if (a != NULL_TREE)
-	    check_function_arguments_recurse (check_nonnull_arg, NULL,
+	    check_function_arguments_recurse (check_nonnull_arg, &loc,
 					      argarray[i], i + 1);
 	}
     }
@@ -9737,9 +9735,10 @@ nonnull_check_p (tree args, unsigned HOST_WIDE_INT param_num)
    via check_function_arguments_recurse.  */
 
 static void
-check_nonnull_arg (void * ARG_UNUSED (ctx), tree param,
-		   unsigned HOST_WIDE_INT param_num)
+check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num)
 {
+  location_t *ploc = (location_t *) ctx;
+
   /* Just skip checking the argument if it's not a pointer.  This can
      happen if the "nonnull" attribute was given without an operand
      list (which means to check every pointer argument).  */
@@ -9748,8 +9748,8 @@ check_nonnull_arg (void * ARG_UNUSED (ctx), tree param,
     return;
 
   if (integer_zerop (param))
-    warning (OPT_Wnonnull, "null argument where non-null required "
-	     "(argument %lu)", (unsigned long) param_num);
+    warning_at (*ploc, OPT_Wnonnull, "null argument where non-null required "
+		"(argument %lu)", (unsigned long) param_num);
 }
 
 /* Helper for nonnull attribute handling; fetch the operand number
@@ -10198,15 +10198,17 @@ handle_designated_init_attribute (tree *node, tree name, tree, int,
 
 
 /* Check for valid arguments being passed to a function with FNTYPE.
-   There are NARGS arguments in the array ARGARRAY.  */
+   There are NARGS arguments in the array ARGARRAY.  LOC should be used for
+   diagnostics.  */
 void
-check_function_arguments (const_tree fntype, int nargs, tree *argarray)
+check_function_arguments (location_t loc, const_tree fntype, int nargs,
+			  tree *argarray)
 {
   /* 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.  */
 
   if (warn_nonnull)
-    check_function_nonnull (TYPE_ATTRIBUTES (fntype), nargs, argarray);
+    check_function_nonnull (loc, TYPE_ATTRIBUTES (fntype), nargs, argarray);
 
   /* Check for errors in format strings.  */
 
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index bad8d05..95c0bbf 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -782,7 +782,7 @@ extern const char *fname_as_string (int);
 extern tree fname_decl (location_t, unsigned, tree);
 
 extern int check_user_alignment (const_tree, bool);
-extern void check_function_arguments (const_tree, int, tree *);
+extern void check_function_arguments (location_t loc, const_tree, int, tree *);
 extern void check_function_arguments_recurse (void (*)
 					      (void *, tree,
 					       unsigned HOST_WIDE_INT),
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 741c75c..fa347dc 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3035,7 +3035,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
     return error_mark_node;
 
   /* Check that the arguments to the function are valid.  */
-  check_function_arguments (fntype, nargs, argarray);
+  check_function_arguments (loc, fntype, nargs, argarray);
 
   if (name != NULL_TREE
       && !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 8cdda62..0c12c75 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7512,7 +7512,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       for (j = 0; j < nargs; j++)
 	fargs[j] = maybe_constant_value (argarray[j]);
 
-      check_function_arguments (TREE_TYPE (fn), nargs, fargs);
+      check_function_arguments (input_location, TREE_TYPE (fn), nargs, fargs);
     }
 
   /* Avoid actually calling copy constructors and copy assignment operators,
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 1d2943f..b027554 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -3588,7 +3588,7 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
 
   /* Check for errors in format strings and inappropriately
      null parameters.  */
-  check_function_arguments (fntype, nargs, argarray);
+  check_function_arguments (input_location, fntype, nargs, argarray);
 
   ret = build_cxx_call (function, nargs, argarray, complain);
 
diff --git a/gcc/testsuite/c-c++-common/pr66208.c b/gcc/testsuite/c-c++-common/pr66208.c
new file mode 100644
index 0000000..d394c42
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr66208.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-Wnonnull" } */
+
+void foox (char*, ...) __attribute__ ((nonnull (1)));
+#define foo(p) foox (p, "p is null") /* { dg-warning "null argument" } */
+
+void baz (void)
+{
+  foo (0); /* { dg-message "note: in expansion" } */
+}

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