https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86210
--- Comment #3 from Jakub Jelinek ---
WIP patch to warn also during inlining, with the intent to handle e.g.
int *p = 0;
declared_and_defined(p);
for both C/C++. Unfortunately if it is inlined during early inlining, we still
don't warn, because no forward propagation etc. is done before early inlining.
With -fno-early-inlining -O2 -Wnonnull we don't warn either, because the call
is optimized away, as it is determined const and doesn't use return value.
With a side-effect in there it warns without early inlining.
Is this still worth doing?
--- gcc/tree-ssa-ccp.c.jj 2018-06-13 10:05:30.357110986 +0200
+++ gcc/tree-ssa-ccp.c 2018-06-20 17:14:00.374389421 +0200
@@ -3391,6 +3391,41 @@ make_pass_fold_builtins (gcc::context *c
return new pass_fold_builtins (ctxt);
}
+/* Emit -Wnonnull warnings for call STMT. */
+
+void
+warn_nonnull_call (gcall *stmt)
+{
+ bitmap nonnullargs = get_nonnull_args (gimple_call_fntype (stmt));
+ if (!nonnullargs)
+return;
+
+ for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
+{
+ tree arg = gimple_call_arg (stmt, i);
+ if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
+ continue;
+ if (!integer_zerop (arg))
+ continue;
+ if (!bitmap_empty_p (nonnullargs) && !bitmap_bit_p (nonnullargs, i))
+ continue;
+
+ location_t loc = gimple_location (stmt);
+ if (warning_at (loc, OPT_Wnonnull,
+ "%Gargument %u null where non-null expected",
+ stmt, i + 1))
+ {
+ tree fndecl = gimple_call_fndecl (stmt);
+ if (fndecl && DECL_IS_BUILTIN (fndecl))
+ inform (loc, "in a call to built-in function %qD", fndecl);
+ else if (fndecl)
+ inform (DECL_SOURCE_LOCATION (fndecl),
+ "in a call to function %qD declared here", fndecl);
+ }
+}
+ BITMAP_FREE (nonnullargs);
+}
+
/* A simple pass that emits some warnings post IPA. */
namespace {
@@ -3437,41 +3474,7 @@ pass_post_ipa_warn::execute (function *f
continue;
if (warn_nonnull)
- {
- bitmap nonnullargs
- = get_nonnull_args (gimple_call_fntype (stmt));
- if (nonnullargs)
- {
- for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
- {
- tree arg = gimple_call_arg (stmt, i);
- if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
- continue;
- if (!integer_zerop (arg))
- continue;
- if (!bitmap_empty_p (nonnullargs)
- && !bitmap_bit_p (nonnullargs, i))
- continue;
-
- location_t loc = gimple_location (stmt);
- if (warning_at (loc, OPT_Wnonnull,
- "%Gargument %u null where non-null "
- "expected", as_a (stmt), i + 1))
- {
- tree fndecl = gimple_call_fndecl (stmt);
- if (fndecl && DECL_IS_BUILTIN (fndecl))
- inform (loc, "in a call to built-in function %qD",
- fndecl);
- else if (fndecl)
- inform (DECL_SOURCE_LOCATION (fndecl),
- "in a call to function %qD declared here",
- fndecl);
-
- }
- }
- BITMAP_FREE (nonnullargs);
- }
- }
+ warn_nonnull_call (as_a (stmt));
}
}
return 0;
--- gcc/tree-ssa-ccp.h.jj 2018-01-03 10:19:54.257533814 +0100
+++ gcc/tree-ssa-ccp.h 2018-06-20 17:14:38.915447584 +0200
@@ -26,4 +26,6 @@ void bit_value_binop (enum tree_code, si
void bit_value_unop (enum tree_code, signop, int, widest_int *, widest_int *,
signop, int, const widest_int &, const widest_int &);
+void warn_nonnull_call (gcall *);
+
#endif
--- gcc/tree-inline.c.jj2018-06-20 08:15:41.224868655 +0200
+++ gcc/tree-inline.c 2018-06-20 17:34:39.676261250 +0200
@@ -60,6 +60,7 @@ along with GCC; see the file COPYING3.
#include "stringpool.h"
#include "attribs.h"
#include "sreal.h"
+#include "tree-ssa-ccp.h"
/* I'm not real happy about this, but we need to handle gimple and
non-gimple trees. */
@@ -4409,6 +4410,9 @@ expand_call_inline (basic_block bb, gimp
}
id->src_node = cg_edge->callee;
+ if (warn_nonnull && !gimple_no_warning_p (call_stmt))
+warn_nonnull_call (call_stmt);
+
/* If callee is thunk, all we need is to adjust the THIS pointer
and redirect to function being thunked. */
if (id->src_node->thunk.thunk_p)