https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86210
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- 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 <gcall *>(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 <gcall *>(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.jj 2018-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)