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 = ≈ > + 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 > >