1/* Subclasses of custom_edge_info for describing outcomes of function calls.
2 Copyright (C) 2021-2026 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it
8under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful, but
13WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "analyzer/common.h"
22
23#include "ordered-hash-map.h"
24#include "cfg.h"
25#include "digraph.h"
26#include "sbitmap.h"
27#include "diagnostics/event-id.h"
28
29#include "analyzer/analyzer-logging.h"
30#include "analyzer/supergraph.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#include "analyzer/constraint-manager.h"
36#include "analyzer/sm.h"
37#include "analyzer/pending-diagnostic.h"
38#include "analyzer/region-model-reachability.h"
39#include "analyzer/analyzer-selftests.h"
40#include "analyzer/program-state.h"
41#include "analyzer/checker-path.h"
42#include "analyzer/diagnostic-manager.h"
43#include "analyzer/exploded-graph.h"
44#include "analyzer/call-details.h"
45#include "analyzer/call-info.h"
46
47#if ENABLE_ANALYZER
48
49namespace ana {
50
51/* class custom_edge_info. */
52
53bool
54custom_edge_info::update_state (program_state *state,
55 const exploded_edge *eedge,
56 region_model_context *ctxt) const
57{
58 return update_model (model: state->m_region_model, eedge, ctxt);
59}
60
61void
62custom_edge_info::get_dot_attrs (const char *&out_style,
63 const char *&out_color) const
64{
65 out_color = "red";
66 out_style = "\"dotted\"";
67}
68
69/* Base implementation of custom_edge_info::create_enode vfunc. */
70
71exploded_node *
72custom_edge_info::create_enode (exploded_graph &eg,
73 const program_point &point,
74 program_state &&state,
75 exploded_node *enode_for_diag,
76 region_model_context *) const
77{
78 return eg.get_or_create_node (point, state, enode_for_diag);
79}
80
81/* class call_info : public custom_edge_info. */
82
83/* Implementation of custom_edge_info::print vfunc for call_info. */
84
85void
86call_info::print (pretty_printer *pp) const
87{
88 gcc_assert (pp);
89 print_desc (pp&: *pp);
90}
91
92/* Implementation of custom_edge_info::add_events_to_path vfunc for
93 call_info: add a custom_event using call_info::get_desc as its
94 description. */
95
96void
97call_info::add_events_to_path (checker_path *emission_path,
98 const exploded_edge &eedge,
99 pending_diagnostic &) const
100{
101 class call_event : public custom_event
102 {
103 public:
104 call_event (const event_loc_info &loc_info,
105 const call_info *call_info)
106 : custom_event (loc_info),
107 m_call_info (call_info)
108 {}
109
110 void print_desc (pretty_printer &pp) const final override
111 {
112 m_call_info->print_desc (pp);
113 }
114
115 private:
116 const call_info *m_call_info;
117 };
118
119 const exploded_node *src_node = eedge.m_src;
120 const program_point &src_point = src_node->get_point ();
121 tree caller_fndecl = src_point.get_fndecl ();
122 const int stack_depth = src_point.get_stack_depth ();
123
124 emission_path->add_event
125 (event: std::make_unique<call_event> (args: event_loc_info (get_call_stmt ().location,
126 caller_fndecl,
127 stack_depth),
128 args: this));
129}
130
131/* Recreate a call_details instance from this call_info. */
132
133call_details
134call_info::get_call_details (region_model *model,
135 region_model_context *ctxt) const
136{
137 return call_details (m_call_stmt, model, ctxt);
138}
139
140/* call_info's ctor.
141
142 The call_info instance will outlive the call_details instance;
143 call_details instances are typically created on the stack. */
144
145call_info::call_info (const call_details &cd)
146: m_call_stmt (cd.get_call_stmt ()),
147 m_fndecl (cd.get_fndecl_for_call ())
148{
149 gcc_assert (m_fndecl);
150}
151
152call_info::call_info (const call_details &cd,
153 const function &called_fn)
154: m_call_stmt (cd.get_call_stmt ()),
155 m_fndecl (called_fn.decl)
156{
157 gcc_assert (m_fndecl);
158}
159
160/* class succeed_or_fail_call_info : public call_info. */
161
162void
163succeed_or_fail_call_info::print_desc (pretty_printer &pp) const
164{
165 if (m_success)
166 pp_printf (&pp, "when %qE succeeds", get_fndecl ());
167 else
168 pp_printf (&pp, "when %qE fails", get_fndecl ());
169}
170
171} // namespace ana
172
173#endif /* #if ENABLE_ANALYZER */
174

source code of gcc/analyzer/call-info.cc