LCOV - code coverage report
Current view: top level - gcc - gimple-ssa-nonnull-compare.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 82.4 % 51 42
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* -Wnonnull-compare warning support.
       2              :    Copyright (C) 2016-2026 Free Software Foundation, Inc.
       3              :    Contributed by Jakub Jelinek <jakub@redhat.com>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify
       8              : it under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful,
      13              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15              : GNU General Public License for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "backend.h"
      25              : #include "tree.h"
      26              : #include "gimple.h"
      27              : #include "tree-pass.h"
      28              : #include "ssa.h"
      29              : #include "diagnostic-core.h"
      30              : #include "tree-dfa.h"
      31              : 
      32              : /* Warn about comparison of nonnull_arg_p argument initial values
      33              :    with NULL.  */
      34              : 
      35              : static void
      36       737048 : do_warn_nonnull_compare (function *fun, tree arg)
      37              : {
      38      1215537 :   if (!POINTER_TYPE_P (TREE_TYPE (arg))
      39      1189219 :       && TREE_CODE (TREE_TYPE (arg)) != OFFSET_TYPE)
      40       666671 :     return;
      41              : 
      42       284925 :   if (!nonnull_arg_p (arg))
      43              :     return;
      44              : 
      45        78553 :   tree d = ssa_default_def (fun, arg);
      46        78553 :   if (d == NULL_TREE)
      47              :     return;
      48              : 
      49        70377 :   use_operand_p use_p;
      50        70377 :   imm_use_iterator iter;
      51              : 
      52       324108 :   FOR_EACH_IMM_USE_FAST (use_p, iter, d)
      53              :     {
      54       183354 :       gimple *stmt = USE_STMT (use_p);
      55       183354 :       tree op = NULL_TREE;
      56       183354 :       location_t loc = gimple_location (stmt);
      57       183354 :       if (gimple_code (stmt) == GIMPLE_COND)
      58          332 :         switch (gimple_cond_code (stmt))
      59              :           {
      60          316 :           case EQ_EXPR:
      61          316 :           case NE_EXPR:
      62          316 :             if (gimple_cond_lhs (stmt) == d)
      63          218 :               op = gimple_cond_rhs (stmt);
      64              :             break;
      65              :           default:
      66              :             break;
      67              :           }
      68       183022 :       else if (is_gimple_assign (stmt))
      69       123895 :         switch (gimple_assign_rhs_code (stmt))
      70              :           {
      71          266 :           case EQ_EXPR:
      72          266 :           case NE_EXPR:
      73          266 :             if (gimple_assign_rhs1 (stmt) == d)
      74          223 :               op = gimple_assign_rhs2 (stmt);
      75              :             break;
      76            0 :           case COND_EXPR:
      77            0 :             switch (TREE_CODE (gimple_assign_rhs1 (stmt)))
      78              :               {
      79            0 :               case EQ_EXPR:
      80            0 :               case NE_EXPR:
      81            0 :                 op = gimple_assign_rhs1 (stmt);
      82            0 :                 if (TREE_OPERAND (op, 0) != d)
      83              :                   {
      84              :                     op = NULL_TREE;
      85              :                     break;
      86              :                   }
      87            0 :                 loc = EXPR_LOC_OR_LOC (op, loc);
      88            0 :                 op = TREE_OPERAND (op, 1);
      89            0 :                 break;
      90              :               default:
      91              :                 break;
      92              :               }
      93              :             break;
      94              :           default:
      95              :             break;
      96              :           }
      97          441 :       if (op
      98         1044 :           && (POINTER_TYPE_P (TREE_TYPE (arg))
      99          441 :               ? integer_zerop (op) : integer_minus_onep (op))
     100          949 :           && !warning_suppressed_p (stmt, OPT_Wnonnull_compare))
     101           42 :         warning_at (loc, OPT_Wnonnull_compare,
     102              :                     "%<nonnull%> argument %qD compared to NULL", arg);
     103        70377 :     }
     104              : }
     105              : 
     106              : namespace {
     107              : 
     108              : const pass_data pass_data_warn_nonnull_compare =
     109              : {
     110              :   GIMPLE_PASS, /* type */
     111              :   "*nonnullcmp", /* name */
     112              :   OPTGROUP_NONE, /* optinfo_flags */
     113              :   TV_NONE, /* tv_id */
     114              :   PROP_ssa, /* properties_required */
     115              :   0, /* properties_provided */
     116              :   0, /* properties_destroyed */
     117              :   0, /* todo_flags_start */
     118              :   0, /* todo_flags_finish */
     119              : };
     120              : 
     121              : class pass_warn_nonnull_compare : public gimple_opt_pass
     122              : {
     123              : public:
     124       285722 :   pass_warn_nonnull_compare (gcc::context *ctxt)
     125       571444 :     : gimple_opt_pass (pass_data_warn_nonnull_compare, ctxt)
     126              :   {}
     127              : 
     128              :   /* opt_pass methods: */
     129      2848664 :   bool gate (function *) final override { return warn_nonnull_compare; }
     130              : 
     131              :   unsigned int execute (function *) final override;
     132              : 
     133              : }; // class pass_warn_nonnull_compare
     134              : 
     135              : unsigned int
     136       235602 : pass_warn_nonnull_compare::execute (function *fun)
     137              : {
     138       235602 :   if (fun->static_chain_decl)
     139            1 :     do_warn_nonnull_compare (fun, fun->static_chain_decl);
     140              : 
     141       972649 :   for (tree arg = DECL_ARGUMENTS (cfun->decl); arg; arg = DECL_CHAIN (arg))
     142       737047 :     do_warn_nonnull_compare (fun, arg);
     143       235602 :   return 0;
     144              : }
     145              : 
     146              : } // anon namespace
     147              : 
     148              : gimple_opt_pass *
     149       285722 : make_pass_warn_nonnull_compare (gcc::context *ctxt)
     150              : {
     151       285722 :   return new pass_warn_nonnull_compare (ctxt);
     152              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.