On 11/15/19, David Malcolm <[email protected]> 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 <[email protected]>.
> +
> +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 <[email protected]>.
> +
> +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
>
>