From fff1015a51db7fadada35e3b904128b9a42895a6 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 27 Sep 2019 09:30:18 -0400 Subject: [PATCH 45/60] {HAS FIXMES} analyzer: new file: sm-pattern-test.cc This patch adds a custom state machine checker intended purely for DejaGnu testing of the sm "machinery". gcc/ChangeLog: * analyzer/sm-pattern-test.cc: New file. --- gcc/analyzer/sm-pattern-test.cc | 191 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 gcc/analyzer/sm-pattern-test.cc diff --git a/gcc/analyzer/sm-pattern-test.cc b/gcc/analyzer/sm-pattern-test.cc new file mode 100644 index 0000000..cb99662 --- /dev/null +++ b/gcc/analyzer/sm-pattern-test.cc @@ -0,0 +1,191 @@ +/* A state machine for use in DejaGnu tests, to check that + pattern-matching works as expected. + + Copyright (C) 2019 Free Software Foundation, Inc. + Contributed by David Malcolm . + +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 +. */ +/* FIXME. */ +#include "config.h" +#include "gcc-plugin.h" +#include "system.h" +#include "coretypes.h" +#include "tree.h" +#include "tm.h" +#include "toplev.h" +#include "hash-table.h" +#include "vec.h" +#include "ggc.h" +#include "basic-block.h" +#include "tree-ssa-alias.h" +#include "internal-fn.h" +#include "gimple-fold.h" +#include "tree-eh.h" +#include "gimple-expr.h" +#include "is-a.h" +#include "gimple.h" +#include "tree-pass.h" +#include "intl.h" +#include "context.h" +#include "diagnostic.h" +#include "bitmap.h" +#include "gimple.h" +#include "gimple-iterator.h" +#include "gimple-pretty-print.h" +#include "tree-pretty-print.h" +#include "analyzer/analyzer.h" +#include "analyzer/graphviz.h" +#include "cgraph.h" +#include "diagnostic-path.h" +#include "gcc-rich-location.h" +#include +#include "analyzer/supergraph.h" +#include "analyzer/sm.h" +#include "analyzer/pending-diagnostic.h" + +static const bool DEBUG = false; +//static const bool DEBUG = true; + +/* A state machine for use in DejaGnu tests, to check that + pattern-matching works as expected. */ + +class pattern_test_state_machine : public state_machine +{ +public: + pattern_test_state_machine (logger *logger); + + bool inherited_state_p () const FINAL OVERRIDE { return false; } + + bool on_stmt (sm_context *sm_ctxt, + const supernode *node, + const gimple *stmt) const FINAL OVERRIDE; + + void on_condition (sm_context *sm_ctxt, + const supernode *node, + const gimple *stmt, + tree lhs, + enum tree_code op, + tree rhs) const FINAL OVERRIDE; + + void on_leak (sm_context *sm_ctxt, + const supernode *node, + const gimple *stmt, + tree var, + state_machine::state_t state) const FINAL OVERRIDE; + bool can_purge_p (state_t s) const FINAL OVERRIDE; + +private: + state_t m_start; +}; + +//////////////////////////////////////////////////////////////////////////// + +class pattern_match : public pending_diagnostic_subclass +{ +public: + pattern_match (tree lhs, enum tree_code op, tree rhs) + : m_lhs (lhs), m_op (op), m_rhs (rhs) {} + + const char *get_kind () const FINAL OVERRIDE { return "pattern_match"; } + + bool operator== (const pattern_match &other) const + { + return (m_lhs == other.m_lhs + && m_op == other.m_op + && m_rhs == other.m_rhs); + } + + void emit (rich_location *rich_loc) FINAL OVERRIDE + { + warning_at (rich_loc, 0, "pattern match on %<%E %s %E%>", + m_lhs, op_symbol_code (m_op), m_rhs); + } + +private: + tree m_lhs; + enum tree_code m_op; + tree m_rhs; +}; + +//////////////////////////////////////////////////////////////////////////// + +pattern_test_state_machine::pattern_test_state_machine (logger *logger) +: state_machine ("pattern-test", logger) +{ + // TODO: parse all of this from a file: + m_start = add_state ("start"); +} + +bool +pattern_test_state_machine::on_stmt (sm_context *sm_ctxt ATTRIBUTE_UNUSED, + const supernode *node ATTRIBUTE_UNUSED, + const gimple *stmt ATTRIBUTE_UNUSED) const +{ + //tree fndecl = node->m_fun->decl; + +#if 0 + // FIXME: do all of this from data + if (const gcall *call = dyn_cast (stmt)) + { + } +#endif + return false; +} + +/* FIXME. */ + +void +pattern_test_state_machine::on_condition (sm_context *sm_ctxt, + const supernode *node, + const gimple *stmt, + tree lhs, + enum tree_code op, + tree rhs) const +{ + if (stmt == NULL) + return; + + if (!CONSTANT_CLASS_P (rhs)) + return; + + pending_diagnostic *diag = new pattern_match (lhs, op, rhs); + sm_ctxt->warn_for_state (node, stmt, lhs, m_start, diag); +} + +void +pattern_test_state_machine::on_leak (sm_context *sm_ctxt ATTRIBUTE_UNUSED, + const supernode *node ATTRIBUTE_UNUSED, + const gimple *stmt ATTRIBUTE_UNUSED, + tree var ATTRIBUTE_UNUSED, + state_machine::state_t state + ATTRIBUTE_UNUSED) + const +{ + /* Empty. */ +} + +bool +pattern_test_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const +{ + return true; +} + +state_machine * +make_pattern_test_state_machine (logger *logger) +{ + return new pattern_test_state_machine (logger); +} -- 1.8.5.3