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)

Reply via email to