aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2020-06-28 14:22:14 -0600
committerMartin Sebor <msebor@redhat.com>2020-06-28 14:24:52 -0600
commit75ff24e1920ea6b198350a2961e23175e6108e75 (patch)
tree88dfd1e43a652ff5f769d9543cd22d764cbe29e3 /gcc/c-family
parentce56fd949f359a62b86a45aaf975ac2ecc48fa64 (diff)
downloadgcc-75ff24e1920ea6b198350a2961e23175e6108e75.zip
gcc-75ff24e1920ea6b198350a2961e23175e6108e75.tar.gz
gcc-75ff24e1920ea6b198350a2961e23175e6108e75.tar.bz2
Underline argument in -Wnonnull and in C++ extend warning to the this pointer [PR c++/86568].
Resolves: PR c++/86568 - -Wnonnull warnings should highlight the relevant argument not the closing parenthesis gcc/c-family/ChangeLog: PR c++/86568 * c-common.c (struct nonnull_arg_ctx): Add members. (check_function_nonnull): Use nonnull_arg_ctx as argument. Handle C++ member functions specially. Consider the this pointer implicitly nonnull. (check_nonnull_arg): Use location of argument when available. (check_function_arguments): Use nonnull_arg_ctx as argument. gcc/ChangeLog: PR c++/86568 * calls.c (maybe_warn_rdwr_sizes): Use location of argument if available. * tree-ssa-ccp.c (pass_post_ipa_warn::execute): Same. Adjust indentation. * tree.c (get_nonnull_args): Consider the this pointer implicitly nonnull. * var-tracking.c (deps_vec): New type. (var_loc_dep_vec): New function. (VAR_LOC_DEP_VEC): Use it. gcc/testsuite/ChangeLog: PR c++/86568 * g++.dg/warn/Wnonnull5.C: New test. * c-c++-common/pr28656.c: Adjust text of expected warning. * c-c++-common/pr66208.c: Same. * g++.dg/cpp0x/nullptr22.C: Same. * g++.dg/ext/attr-nonnull.C: Same. * g++.dg/ext/attrib49.C: Same. * g++.dg/pr71973-2.C: Same. * g++.dg/warn/Wnonnull3.C: Same. * g++.dg/warn/Wnonnull4.C: Same. * obj-c++.dg/attributes/method-nonnull-1.mm: Same. * objc.dg/attributes/method-nonnull-1.m: Same.
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/c-common.c83
1 files changed, 62 insertions, 21 deletions
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index a9fa0d1..cfd12c0 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5288,26 +5288,39 @@ c_determine_visibility (tree decl)
struct nonnull_arg_ctx
{
+ /* Location of the call. */
location_t loc;
+ /* The function whose arguments are being checked and its type (used
+ for calls through function pointers). */
+ const_tree fndecl, fntype;
+ /* True if a warning has been issued. */
bool warned_p;
};
-/* 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. Return true if we have
- warned. */
+/* Check the argument list of a function call to CTX.FNDECL of CTX.FNTYPE
+ for null in argument slots that are marked as requiring a non-null
+ pointer argument. The NARGS arguments are passed in the array ARGARRAY.
+ Return true if we have warned. */
static bool
-check_function_nonnull (location_t loc, tree attrs, int nargs, tree *argarray)
+check_function_nonnull (nonnull_arg_ctx &ctx, int nargs, tree *argarray)
{
- tree a;
- int i;
+ int firstarg = 0;
+ if (TREE_CODE (ctx.fntype) == METHOD_TYPE)
+ {
+ /* In calls to C++ non-static member functions check the this
+ pointer regardless of whether the function is declared with
+ attribute nonnull. */
+ firstarg = 1;
+ check_function_arguments_recurse (check_nonnull_arg, &ctx, argarray[0],
+ firstarg);
+ }
- attrs = lookup_attribute ("nonnull", attrs);
+ tree attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (ctx.fntype));
if (attrs == NULL_TREE)
- return false;
+ return ctx.warned_p;
- a = attrs;
+ tree a = attrs;
/* See if any of the nonnull attributes has no arguments. If so,
then every pointer argument is checked (in which case the check
for pointer type is done in check_nonnull_arg). */
@@ -5316,16 +5329,15 @@ check_function_nonnull (location_t loc, tree attrs, int nargs, tree *argarray)
a = lookup_attribute ("nonnull", TREE_CHAIN (a));
while (a != NULL_TREE && TREE_VALUE (a) != NULL_TREE);
- struct nonnull_arg_ctx ctx = { loc, false };
if (a != NULL_TREE)
- for (i = 0; i < nargs; i++)
+ for (int i = firstarg; i < nargs; i++)
check_function_arguments_recurse (check_nonnull_arg, &ctx, argarray[i],
i + 1);
else
{
/* Walk the argument list. If we encounter an argument number we
should check for non-null, do it. */
- for (i = 0; i < nargs; i++)
+ for (int i = firstarg; i < nargs; i++)
{
for (a = attrs; ; a = TREE_CHAIN (a))
{
@@ -5495,12 +5507,39 @@ check_nonnull_arg (void *ctx, tree param, unsigned HOST_WIDE_INT param_num)
return;
/* Diagnose the simple cases of null arguments. */
- if (integer_zerop (fold_for_warn (param)))
+ if (!integer_zerop (fold_for_warn (param)))
+ return;
+
+ auto_diagnostic_group adg;
+
+ const location_t loc = EXPR_LOC_OR_LOC (param, pctx->loc);
+
+ if (TREE_CODE (pctx->fntype) == METHOD_TYPE)
+ --param_num;
+
+ bool warned;
+ if (param_num == 0)
+ {
+ warned = warning_at (loc, OPT_Wnonnull,
+ "%qs pointer null", "this");
+ if (pctx->fndecl)
+ inform (DECL_SOURCE_LOCATION (pctx->fndecl),
+ "in a call to non-static member function %qD",
+ pctx->fndecl);
+ }
+ else
{
- warning_at (pctx->loc, OPT_Wnonnull, "null argument where non-null "
- "required (argument %lu)", (unsigned long) param_num);
- pctx->warned_p = true;
+ warned = warning_at (loc, OPT_Wnonnull,
+ "argument %u null where non-null expected",
+ (unsigned) param_num);
+ if (pctx->fndecl)
+ inform (DECL_SOURCE_LOCATION (pctx->fndecl),
+ "in a call to function %qD declared %qs",
+ pctx->fndecl, "nonnull");
}
+
+ if (warned)
+ pctx->warned_p = true;
}
/* Helper for attribute handling; fetch the operand number from
@@ -5717,11 +5756,13 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype,
bool warned_p = false;
/* 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. */
-
+ non-null. In C++, this includes the this pointer. We also need
+ to do this if format checking is enabled. */
if (warn_nonnull)
- warned_p = check_function_nonnull (loc, TYPE_ATTRIBUTES (fntype),
- nargs, argarray);
+ {
+ nonnull_arg_ctx ctx = { loc, fndecl, fntype, false };
+ warned_p = check_function_nonnull (ctx, nargs, argarray);
+ }
/* Check for errors in format strings. */