(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
plugin/
diagnostic_plugin_test_metadata.c
       1  /* This plugin exercises diagnostic_metadata.  */
       2  
       3  #include "gcc-plugin.h"
       4  #include "config.h"
       5  #include "system.h"
       6  #include "coretypes.h"
       7  #include "tm.h"
       8  #include "tree.h"
       9  #include "stringpool.h"
      10  #include "toplev.h"
      11  #include "basic-block.h"
      12  #include "hash-table.h"
      13  #include "vec.h"
      14  #include "ggc.h"
      15  #include "basic-block.h"
      16  #include "tree-ssa-alias.h"
      17  #include "internal-fn.h"
      18  #include "gimple.h"
      19  #include "gimple-iterator.h"
      20  #include "gimple-fold.h"
      21  #include "tree-eh.h"
      22  #include "gimple-expr.h"
      23  #include "is-a.h"
      24  #include "tree.h"
      25  #include "tree-pass.h"
      26  #include "intl.h"
      27  #include "plugin-version.h"
      28  #include "diagnostic.h"
      29  #include "context.h"
      30  #include "gcc-rich-location.h"
      31  #include "diagnostic-metadata.h"
      32  
      33  int plugin_is_GPL_compatible;
      34  
      35  const pass_data pass_data_test_metadata =
      36  {
      37    GIMPLE_PASS, /* type */
      38    "test_metadata", /* name */
      39    OPTGROUP_NONE, /* optinfo_flags */
      40    TV_NONE, /* tv_id */
      41    PROP_ssa, /* properties_required */
      42    0, /* properties_provided */
      43    0, /* properties_destroyed */
      44    0, /* todo_flags_start */
      45    0, /* todo_flags_finish */
      46  };
      47  
      48  class pass_test_metadata : public gimple_opt_pass
      49  {
      50  public:
      51    pass_test_metadata(gcc::context *ctxt)
      52      : gimple_opt_pass(pass_data_test_metadata, ctxt)
      53    {}
      54  
      55    /* opt_pass methods: */
      56    bool gate (function *) { return true; }
      57    virtual unsigned int execute (function *);
      58  
      59  }; // class pass_test_metadata
      60  
      61  /* Determine if STMT is a call with NUM_ARGS arguments to a function
      62     named FUNCNAME.
      63     If so, return STMT as a gcall *.  Otherwise return NULL.  */
      64  
      65  static gcall *
      66  check_for_named_call (gimple *stmt,
      67  		      const char *funcname, unsigned int num_args)
      68  {
      69    gcc_assert (funcname);
      70  
      71    gcall *call = dyn_cast <gcall *> (stmt);
      72    if (!call)
      73      return NULL;
      74  
      75    tree fndecl = gimple_call_fndecl (call);
      76    if (!fndecl)
      77      return NULL;
      78  
      79    if (strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname))
      80      return NULL;
      81  
      82    if (gimple_call_num_args (call) != num_args)
      83      {
      84        error_at (stmt->location, "expected number of args: %i (got %i)",
      85  		num_args, gimple_call_num_args (call));
      86        return NULL;
      87      }
      88  
      89    return call;
      90  }
      91  
      92  /* Exercise diagnostic_metadata.  */
      93  
      94  unsigned int
      95  pass_test_metadata::execute (function *fun)
      96  {
      97    gimple_stmt_iterator gsi;
      98    basic_block bb;
      99  
     100    FOR_EACH_BB_FN (bb, fun)
     101      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
     102        {
     103  	gimple *stmt = gsi_stmt (gsi);
     104  
     105  	/* Example of CWE: complain about uses of gets.  */
     106  	if (gcall *call = check_for_named_call (stmt, "gets", 1))
     107  	  {
     108  	    gcc_rich_location richloc (gimple_location (call));
     109  	    diagnostic_metadata m;
     110  
     111  	    /* CWE-242: Use of Inherently Dangerous Function.  */
     112  	    m.add_cwe (242);
     113  
     114  	    /* Example of a diagnostic_metadata::rule.  */
     115  	    diagnostic_metadata::precanned_rule
     116  	      test_rule ("STR34-C", "https://example.com/");
     117  	    m.add_rule (test_rule);
     118  
     119  	    warning_meta (&richloc, m, 0,
     120  			  "never use %qs", "gets");
     121  	  }
     122        }
     123  
     124    return 0;
     125  }
     126  
     127  int
     128  plugin_init (struct plugin_name_args *plugin_info,
     129  	     struct plugin_gcc_version *version)
     130  {
     131    struct register_pass_info pass_info;
     132    const char *plugin_name = plugin_info->base_name;
     133    int argc = plugin_info->argc;
     134    struct plugin_argument *argv = plugin_info->argv;
     135  
     136    if (!plugin_default_version_check (version, &gcc_version))
     137      return 1;
     138  
     139    pass_info.pass = new pass_test_metadata (g);
     140    pass_info.reference_pass_name = "ssa";
     141    pass_info.ref_pass_instance_number = 1;
     142    pass_info.pos_op = PASS_POS_INSERT_AFTER;
     143    register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
     144  		     &pass_info);
     145  
     146    return 0;
     147  }