]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/analyzer/sm-pattern-test.cc
analyzer: eliminate sm_context::warn_for_state in favor of a new 'warn' vfunc
[thirdparty/gcc.git] / gcc / analyzer / sm-pattern-test.cc
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
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3, or (at your option)
12 any later version.
13
14 GCC is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along 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
42 namespace ana {
43
44 namespace {
45
46 /* A state machine for use in DejaGnu tests, to check that
47 pattern-matching works as expected. */
48
49 class pattern_test_state_machine : public state_machine
50 {
51 public:
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 };
69
70 class pattern_match : public pending_diagnostic_subclass<pattern_match>
71 {
72 public:
73 pattern_match (tree lhs, enum tree_code op, tree rhs)
74 : m_lhs (lhs), m_op (op), m_rhs (rhs) {}
75
76 const char *get_kind () const FINAL OVERRIDE { return "pattern_match"; }
77
78 bool operator== (const pattern_match &other) const
79 {
80 return (same_tree_p (m_lhs, other.m_lhs)
81 && m_op == other.m_op
82 && same_tree_p (m_rhs, other.m_rhs));
83 }
84
85 bool emit (rich_location *rich_loc) FINAL OVERRIDE
86 {
87 return warning_at (rich_loc, 0, "pattern match on %<%E %s %E%>",
88 m_lhs, op_symbol_code (m_op), m_rhs);
89 }
90
91 private:
92 tree m_lhs;
93 enum tree_code m_op;
94 tree m_rhs;
95 };
96
97 pattern_test_state_machine::pattern_test_state_machine (logger *logger)
98 : state_machine ("pattern-test", logger)
99 {
100 }
101
102 bool
103 pattern_test_state_machine::on_stmt (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
104 const supernode *node ATTRIBUTE_UNUSED,
105 const gimple *stmt ATTRIBUTE_UNUSED) const
106 {
107 return false;
108 }
109
110 /* Implementation of state_machine::on_condition vfunc for
111 pattern_test_state_machine.
112
113 Queue a pattern_match diagnostic for any comparison against a
114 constant. */
115
116 void
117 pattern_test_state_machine::on_condition (sm_context *sm_ctxt,
118 const supernode *node,
119 const gimple *stmt,
120 tree lhs,
121 enum tree_code op,
122 tree rhs) const
123 {
124 if (stmt == NULL)
125 return;
126
127 if (!CONSTANT_CLASS_P (rhs))
128 return;
129
130 pending_diagnostic *diag = new pattern_match (lhs, op, rhs);
131 sm_ctxt->warn (node, stmt, lhs, diag);
132 }
133
134 bool
135 pattern_test_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
136 {
137 return true;
138 }
139
140 } // anonymous namespace
141
142 /* Internal interface to this file. */
143
144 state_machine *
145 make_pattern_test_state_machine (logger *logger)
146 {
147 return new pattern_test_state_machine (logger);
148 }
149
150 } // namespace ana
151
152 #endif /* #if ENABLE_ANALYZER */