1/* A state machine for use in DejaGnu tests, to check that 2 pattern-matching works as expected. 3 4 Copyright (C) 2019-2020 Free Software Foundation, Inc. 5 Contributed by David Malcolm <dmalcolm@redhat.com>. 6 7This file is part of GCC. 8 9GCC is free software; you can redistribute it and/or modify it 10under the terms of the GNU General Public License as published by 11the Free Software Foundation; either version 3, or (at your option) 12any later version. 13 14GCC is distributed in the hope that it will be useful, but 15WITHOUT ANY WARRANTY; without even the implied warranty of 16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17General Public License for more details. 18 19You should have received a copy of the GNU General Public License 20along with GCC; see the file COPYING3. If not see 21<http://www.gnu.org/licenses/>. */ 22 23#include "config.h" 24#include "system.h" 25#include "coretypes.h" 26#include "tree.h" 27#include "function.h" 28#include "basic-block.h" 29#include "gimple.h" 30#include "tree-pretty-print.h" 31#include "diagnostic-path.h" 32#include "diagnostic-metadata.h" 33#include "function.h" 34#include "analyzer/analyzer.h" 35#include "diagnostic-event-id.h" 36#include "analyzer/analyzer-logging.h" 37#include "analyzer/sm.h" 38#include "analyzer/pending-diagnostic.h" 39 40#if ENABLE_ANALYZER 41 42namespace ana { 43 44namespace { 45 46/* A state machine for use in DejaGnu tests, to check that 47 pattern-matching works as expected. */ 48 49class pattern_test_state_machine : public state_machine 50{ 51public: 52 pattern_test_state_machine (logger *logger); 53 54 bool inherited_state_p () const FINAL OVERRIDE { return false; } 55 56 bool on_stmt (sm_context *sm_ctxt, 57 const supernode *node, 58 const gimple *stmt) const FINAL OVERRIDE; 59 60 void on_condition (sm_context *sm_ctxt, 61 const supernode *node, 62 const gimple *stmt, 63 tree lhs, 64 enum tree_code op, 65 tree rhs) const FINAL OVERRIDE; 66 67 bool can_purge_p (state_t s) const FINAL OVERRIDE; 68 69private: 70 state_t m_start; 71}; 72 73class pattern_match : public pending_diagnostic_subclass<pattern_match> 74{ 75public: 76 pattern_match (tree lhs, enum tree_code op, tree rhs) 77 : m_lhs (lhs), m_op (op), m_rhs (rhs) {} 78 79 const char *get_kind () const FINAL OVERRIDE { return "pattern_match"; } 80 81 bool operator== (const pattern_match &other) const 82 { 83 return (same_tree_p (m_lhs, other.m_lhs) 84 && m_op == other.m_op 85 && same_tree_p (m_rhs, other.m_rhs)); 86 } 87 88 bool emit (rich_location *rich_loc) FINAL OVERRIDE 89 { 90 return warning_at (rich_loc, 0, "pattern match on %<%E %s %E%>", 91 m_lhs, op_symbol_code (m_op), m_rhs); 92 } 93 94private: 95 tree m_lhs; 96 enum tree_code m_op; 97 tree m_rhs; 98}; 99 100pattern_test_state_machine::pattern_test_state_machine (logger *logger) 101: state_machine ("pattern-test", logger) 102{ 103 m_start = add_state ("start"); 104} 105 106bool 107pattern_test_state_machine::on_stmt (sm_context *sm_ctxt ATTRIBUTE_UNUSED, 108 const supernode *node ATTRIBUTE_UNUSED, 109 const gimple *stmt ATTRIBUTE_UNUSED) const 110{ 111 return false; 112} 113 114/* Implementation of state_machine::on_condition vfunc for 115 pattern_test_state_machine. 116 117 Queue a pattern_match diagnostic for any comparison against a 118 constant. */ 119 120void 121pattern_test_state_machine::on_condition (sm_context *sm_ctxt, 122 const supernode *node, 123 const gimple *stmt, 124 tree lhs, 125 enum tree_code op, 126 tree rhs) const 127{ 128 if (stmt == NULL) 129 return; 130 131 if (!CONSTANT_CLASS_P (rhs)) 132 return; 133 134 pending_diagnostic *diag = new pattern_match (lhs, op, rhs); 135 sm_ctxt->warn_for_state (node, stmt, lhs, m_start, diag); 136} 137 138bool 139pattern_test_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const 140{ 141 return true; 142} 143 144} // anonymous namespace 145 146/* Internal interface to this file. */ 147 148state_machine * 149make_pattern_test_state_machine (logger *logger) 150{ 151 return new pattern_test_state_machine (logger); 152} 153 154} // namespace ana 155 156#endif /* #if ENABLE_ANALYZER */ 157