On 11/15/19, David Malcolm <dmalc...@redhat.com> wrote:
> gcc/ChangeLog:
>       * analyzer/analyzer.cc: New file.
>       * analyzer/analyzer.h: New file.
> ---
>  gcc/analyzer/analyzer.cc | 125
> ++++++++++++++++++++++++++++++++++++++++++++++
>  gcc/analyzer/analyzer.h  | 126
> +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 251 insertions(+)
>  create mode 100644 gcc/analyzer/analyzer.cc
>  create mode 100644 gcc/analyzer/analyzer.h
>
> diff --git a/gcc/analyzer/analyzer.cc b/gcc/analyzer/analyzer.cc
> new file mode 100644
> index 0000000..399925c
> --- /dev/null
> +++ b/gcc/analyzer/analyzer.cc
> @@ -0,0 +1,125 @@
> +/* Utility functions for the analyzer.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   Contributed by David Malcolm <dmalc...@redhat.com>.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it
> +under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful, but
> +WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include "gcc-plugin.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "tree.h"
> +#include "gimple.h"
> +#include "diagnostic.h"
> +#include "intl.h"
> +#include "analyzer/analyzer.h"
> +
> +/* Helper function for checkers.  Is the CALL to the given function name?
> */
> +
> +bool
> +is_named_call_p (const gcall *call, const char *funcname)
> +{
> +  gcc_assert (funcname);
> +
> +  tree fndecl = gimple_call_fndecl (call);
> +  if (!fndecl)
> +    return false;
> +
> +  return 0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname);
> +}
> +
> +/* Helper function for checkers.  Is the CALL to the given function name,
> +   and with the given number of arguments?  */
> +
> +bool
> +is_named_call_p (const gcall *call, const char *funcname,
> +              unsigned int num_args)
> +{
> +  gcc_assert (funcname);
> +
> +  if (!is_named_call_p (call, funcname))
> +    return false;
> +
> +  if (gimple_call_num_args (call) != num_args)
> +    return false;
> +
> +  return true;
> +}
> +
> +/* Return true if stmt is a setjmp call.  */
> +
> +bool
> +is_setjmp_call_p (const gimple *stmt)
> +{
> +  /* TODO: is there a less hacky way to check for "setjmp"?  */
> +  if (const gcall *call = dyn_cast <const gcall *> (stmt))
> +    if (is_named_call_p (call, "_setjmp", 1))
> +      return true;
> +
> +  return false;
> +}
> +
> +/* Return true if stmt is a longjmp call.  */
> +
> +bool
> +is_longjmp_call_p (const gcall *call)
> +{
> +  /* TODO: is there a less hacky way to check for "longjmp"?  */
> +  if (is_named_call_p (call, "longjmp", 2))
> +    return true;
> +
> +  return false;
> +}
> +
> +/* Generate a label_text instance by formatting FMT, using a
> +   temporary clone of the global_dc's printer (thus using its
> +   formatting callbacks).
> +
> +   Colorize if the global_dc supports colorization and CAN_COLORIZE is
> +   true.  */
> +
> +label_text
> +make_label_text (bool can_colorize, const char *fmt, ...)
> +{
> +  pretty_printer *pp = global_dc->printer->clone ();
> +  pp_clear_output_area (pp);
> +
> +  if (!can_colorize)
> +    pp_show_color (pp) = false;
> +
> +  text_info ti;
> +  rich_location rich_loc (line_table, UNKNOWN_LOCATION);
> +
> +  va_list ap;
> +
> +  va_start (ap, fmt);
> +
> +  ti.format_spec = _(fmt);
> +  ti.args_ptr = &ap;
> +  ti.err_no = 0;
> +  ti.x_data = NULL;
> +  ti.m_richloc = &rich_loc;
> +
> +  pp_format (pp, &ti);
> +  pp_output_formatted_text (pp);
> +
> +  va_end (ap);
> +
> +  label_text result = label_text::take (xstrdup (pp_formatted_text (pp)));
> +  delete pp;
> +  return result;
> +}
> diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
> new file mode 100644
> index 0000000..ace8924
> --- /dev/null
> +++ b/gcc/analyzer/analyzer.h
> @@ -0,0 +1,126 @@
> +/* Utility functions for the analyzer.
> +   Copyright (C) 2019 Free Software Foundation, Inc.
> +   Contributed by David Malcolm <dmalc...@redhat.com>.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it
> +under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful, but
> +WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#ifndef GCC_ANALYZER_ANALYZER_H
> +#define GCC_ANALYZER_ANALYZER_H
> +
> +/* Forward decls of common types, with indentation to show inheritance. */

I'm wondering about the "with indentation to show inheritance" part...
does that require tweaking any editor configuration files or adding
/*INDENT-OFF*/ comments or anything to prevent automatic formatting
tools from "fixing" the indentation to go back to the normal style of
having everything be aligned?

> +
> +class graphviz_out;
> +class supergraph;
> +class supernode;
> +class superedge;
> +  class cfg_superedge;
> +    class switch_cfg_superedge;
> +  class callgraph_superedge;
> +    class call_superedge;
> +    class return_superedge;
> +class svalue;
> +  class region_svalue;
> +  class constant_svalue;
> +  class poisoned_svalue;
> +  class unknown_svalue;
> +  class setjmp_svalue;
> +class region;
> +  class map_region;
> +  class symbolic_region;
> +class region_model;
> +class region_model_context;
> +  class impl_region_model_context;
> +class constraint_manager;
> +class equiv_class;
> +struct model_merger;
> +struct svalue_id_merger_mapping;
> +struct canonicalization;
> +class pending_diagnostic;
> +class checker_path;
> +class extrinsic_state;
> +class sm_state_map;
> +class stmt_finder;
> +class program_point;
> +class program_state;
> +class exploded_graph;
> +class exploded_node;
> +class exploded_edge;
> +class exploded_cluster;
> +class exploded_path;
> +class analysis_plan;
> +class state_purge_map;
> +class state_purge_per_ssa_name;
> +class state_change;
> +
> +////////////////////////////////////////////////////////////////////////////
> +
> +extern bool is_named_call_p (const gcall *call, const char *funcname);
> +extern bool is_named_call_p (const gcall *call, const char *funcname,
> +                          unsigned int num_args);
> +extern bool is_setjmp_call_p (const gimple *stmt);
> +extern bool is_longjmp_call_p (const gcall *call);
> +
> +extern void register_analyzer_pass ();
> +
> +extern label_text make_label_text (bool can_colorize, const char *fmt,
> ...);
> +
> +////////////////////////////////////////////////////////////////////////////
> +
> +/* An RAII-style class for pushing/popping cfun within a scope.
> +   Doing so ensures we get "In function " announcements
> +   from the diagnostics subsystem.  */
> +
> +class auto_cfun
> +{
> +public:
> +  auto_cfun (function *fun) { push_cfun (fun); }
> +  ~auto_cfun () { pop_cfun (); }
> +};
> +
> +////////////////////////////////////////////////////////////////////////////
> +
> +/* Begin suppressing -Wformat and -Wformat-extra-args.  */
> +
> +#define PUSH_IGNORE_WFORMAT \
> +  _Pragma("GCC diagnostic push") \
> +  _Pragma("GCC diagnostic ignored \"-Wformat\"") \
> +  _Pragma("GCC diagnostic ignored \"-Wformat-extra-args\"")
> +
> +/* Finish suppressing -Wformat and -Wformat-extra-args.  */
> +
> +#define POP_IGNORE_WFORMAT \
> +  _Pragma("GCC diagnostic pop")
> +
> +////////////////////////////////////////////////////////////////////////////
> +
> +/* A template for creating hash traits for a POD type.  */
> +
> +template <typename Type>
> +struct pod_hash_traits : typed_noop_remove<Type>
> +{
> +  typedef Type value_type;
> +  typedef Type compare_type;
> +  static inline hashval_t hash (value_type);
> +  static inline bool equal (const value_type &existing,
> +                         const value_type &candidate);
> +  static inline void mark_deleted (Type &);
> +  static inline void mark_empty (Type &);
> +  static inline bool is_deleted (Type);
> +  static inline bool is_empty (Type);
> +};
> +
> +#endif /* GCC_ANALYZER_ANALYZER_H */
> --
> 1.8.5.3
>
>

Reply via email to