Branch data Line data Source code
1 : : /* A state machine for use in DejaGnu tests, to check that
2 : : pattern-matching works as expected.
3 : :
4 : : Copyright (C) 2019-2026 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 "analyzer/common.h"
24 : :
25 : : #include "tree-pretty-print.h"
26 : : #include "diagnostics/event-id.h"
27 : :
28 : : #include "analyzer/analyzer-logging.h"
29 : : #include "analyzer/sm.h"
30 : : #include "analyzer/pending-diagnostic.h"
31 : : #include "analyzer/call-string.h"
32 : : #include "analyzer/program-point.h"
33 : : #include "analyzer/store.h"
34 : : #include "analyzer/region-model.h"
35 : :
36 : : #if ENABLE_ANALYZER
37 : :
38 : : namespace ana {
39 : :
40 : : namespace {
41 : :
42 : : /* A state machine for use in DejaGnu tests, to check that
43 : : pattern-matching works as expected. */
44 : :
45 : : class pattern_test_state_machine : public state_machine
46 : : {
47 : : public:
48 : : pattern_test_state_machine (logger *logger);
49 : :
50 : 132 : bool inherited_state_p () const final override { return false; }
51 : :
52 : : bool on_stmt (sm_context &sm_ctxt,
53 : : const gimple *stmt) const final override;
54 : :
55 : : void on_condition (sm_context &sm_ctxt,
56 : : const svalue *lhs,
57 : : enum tree_code op,
58 : : const svalue *rhs) const final override;
59 : :
60 : : bool can_purge_p (state_t s) const final override;
61 : : };
62 : :
63 : 0 : class pattern_match : public pending_diagnostic_subclass<pattern_match>
64 : : {
65 : : public:
66 : 32 : pattern_match (tree lhs, enum tree_code op, tree rhs)
67 : 32 : : m_lhs (lhs), m_op (op), m_rhs (rhs) {}
68 : :
69 : 622 : const char *get_kind () const final override { return "pattern_match"; }
70 : :
71 : 71 : bool operator== (const pattern_match &other) const
72 : : {
73 : 71 : return (same_tree_p (m_lhs, other.m_lhs)
74 : 71 : && m_op == other.m_op
75 : 103 : && same_tree_p (m_rhs, other.m_rhs));
76 : : }
77 : :
78 : 64 : int get_controlling_option () const final override
79 : : {
80 : 64 : return 0;
81 : : }
82 : :
83 : 32 : bool emit (diagnostic_emission_context &ctxt) final override
84 : : {
85 : 32 : return ctxt.warn ("pattern match on %<%E %s %E%>",
86 : 32 : m_lhs, op_symbol_code (m_op), m_rhs);
87 : : }
88 : :
89 : : private:
90 : : tree m_lhs;
91 : : enum tree_code m_op;
92 : : tree m_rhs;
93 : : };
94 : :
95 : 10 : pattern_test_state_machine::pattern_test_state_machine (logger *logger)
96 : 10 : : state_machine ("pattern-test", logger)
97 : : {
98 : 0 : }
99 : :
100 : : bool
101 : 74 : pattern_test_state_machine::on_stmt (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
102 : : const gimple *stmt ATTRIBUTE_UNUSED) const
103 : : {
104 : 74 : return false;
105 : : }
106 : :
107 : : /* Implementation of state_machine::on_condition vfunc for
108 : : pattern_test_state_machine.
109 : :
110 : : Queue a pattern_match diagnostic for any comparison against a
111 : : constant. */
112 : :
113 : : void
114 : 32 : pattern_test_state_machine::on_condition (sm_context &sm_ctxt,
115 : : const svalue *lhs,
116 : : enum tree_code op,
117 : : const svalue *rhs) const
118 : : {
119 : 32 : tree rhs_cst = rhs->maybe_get_constant ();
120 : 32 : if (!rhs_cst)
121 : 0 : return;
122 : :
123 : 32 : if (tree lhs_expr = sm_ctxt.get_diagnostic_tree (lhs))
124 : : {
125 : 32 : sm_ctxt.warn (lhs_expr,
126 : 32 : std::make_unique<pattern_match> (lhs_expr, op, rhs_cst));
127 : : }
128 : : }
129 : :
130 : : bool
131 : 100 : pattern_test_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
132 : : {
133 : 100 : return true;
134 : : }
135 : :
136 : : } // anonymous namespace
137 : :
138 : : /* Internal interface to this file. */
139 : :
140 : : std::unique_ptr<state_machine>
141 : 10 : make_pattern_test_state_machine (logger *logger)
142 : : {
143 : 10 : return std::make_unique<pattern_test_state_machine> (logger);
144 : : }
145 : :
146 : : } // namespace ana
147 : :
148 : : #endif /* #if ENABLE_ANALYZER */
|