Branch data Line data Source code
1 : : /* Subclasses of diagnostic_event for analyzer diagnostics.
2 : : Copyright (C) 2019-2024 Free Software Foundation, Inc.
3 : : Contributed by David Malcolm <dmalcolm@redhat.com>.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it
8 : : under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3, or (at your option)
10 : : any later version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but
13 : : WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : General Public License for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : #ifndef GCC_ANALYZER_CHECKER_EVENT_H
22 : : #define GCC_ANALYZER_CHECKER_EVENT_H
23 : :
24 : : #include "tree-logical-location.h"
25 : : #include "analyzer/program-state.h"
26 : : #include "analyzer/event-loc-info.h"
27 : :
28 : : namespace ana {
29 : :
30 : : /* An enum for discriminating between the concrete subclasses of
31 : : checker_event. */
32 : :
33 : : enum event_kind
34 : : {
35 : : EK_DEBUG,
36 : : EK_CUSTOM,
37 : : EK_STMT,
38 : : EK_REGION_CREATION,
39 : : EK_FUNCTION_ENTRY,
40 : : EK_STATE_CHANGE,
41 : : EK_START_CFG_EDGE,
42 : : EK_END_CFG_EDGE,
43 : : EK_CALL_EDGE,
44 : : EK_RETURN_EDGE,
45 : : EK_START_CONSOLIDATED_CFG_EDGES,
46 : : EK_END_CONSOLIDATED_CFG_EDGES,
47 : : EK_INLINED_CALL,
48 : : EK_SETJMP,
49 : : EK_REWIND_FROM_LONGJMP,
50 : : EK_REWIND_TO_SETJMP,
51 : : EK_WARNING
52 : : };
53 : :
54 : : extern const char *event_kind_to_string (enum event_kind ek);
55 : :
56 : : /* Event subclasses.
57 : :
58 : : The class hierarchy looks like this (using indentation to show
59 : : inheritance, and with event_kinds shown for the concrete subclasses):
60 : :
61 : : diagnostic_event
62 : : checker_event
63 : : debug_event (EK_DEBUG)
64 : : custom_event (EK_CUSTOM)
65 : : precanned_custom_event
66 : : statement_event (EK_STMT)
67 : : region_creation_event (EK_REGION_CREATION)
68 : : function_entry_event (EK_FUNCTION_ENTRY)
69 : : state_change_event (EK_STATE_CHANGE)
70 : : superedge_event
71 : : cfg_edge_event
72 : : start_cfg_edge_event (EK_START_CFG_EDGE)
73 : : end_cfg_edge_event (EK_END_CFG_EDGE)
74 : : call_event (EK_CALL_EDGE)
75 : : return_edge (EK_RETURN_EDGE)
76 : : start_consolidated_cfg_edges_event (EK_START_CONSOLIDATED_CFG_EDGES)
77 : : end_consolidated_cfg_edges_event (EK_END_CONSOLIDATED_CFG_EDGES)
78 : : inlined_call_event (EK_INLINED_CALL)
79 : : setjmp_event (EK_SETJMP)
80 : : rewind_event
81 : : rewind_from_longjmp_event (EK_REWIND_FROM_LONGJMP)
82 : : rewind_to_setjmp_event (EK_REWIND_TO_SETJMP)
83 : : warning_event (EK_WARNING). */
84 : :
85 : : /* Abstract subclass of diagnostic_event; the base class for use in
86 : : checker_path (the analyzer's diagnostic_path subclass). */
87 : :
88 : 176 : class checker_event : public diagnostic_event
89 : : {
90 : : public:
91 : : /* Implementation of diagnostic_event. */
92 : :
93 : 56624 : location_t get_location () const final override { return m_loc; }
94 : 15495 : int get_stack_depth () const final override { return m_effective_depth; }
95 : 4763 : const logical_location *get_logical_location () const final override
96 : : {
97 : 4763 : if (m_effective_fndecl)
98 : 4608 : return &m_logical_loc;
99 : : else
100 : : return NULL;
101 : : }
102 : : meaning get_meaning () const override;
103 : 2856 : bool connect_to_next_event_p () const override { return false; }
104 : 3658 : diagnostic_thread_id_t get_thread_id () const final override
105 : : {
106 : 3658 : return 0;
107 : : }
108 : :
109 : : void
110 : : maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj) const override;
111 : :
112 : : /* Additional functionality. */
113 : 11045 : tree get_fndecl () const { return m_effective_fndecl; }
114 : :
115 : 5328 : int get_original_stack_depth () const { return m_original_depth; }
116 : :
117 : : virtual void prepare_for_emission (checker_path *,
118 : : pending_diagnostic *pd,
119 : : diagnostic_event_id_t emission_id);
120 : 21627 : virtual bool is_call_p () const { return false; }
121 : 8 : virtual bool is_function_entry_p () const { return false; }
122 : 16610 : virtual bool is_return_p () const { return false; }
123 : :
124 : : /* For use with %@. */
125 : 290 : const diagnostic_event_id_t *get_id_ptr () const
126 : : {
127 : 290 : return &m_emission_id;
128 : : }
129 : :
130 : : void dump (pretty_printer *pp) const;
131 : : void debug () const;
132 : :
133 : 16485 : void set_location (location_t loc) { m_loc = loc; }
134 : :
135 : : protected:
136 : : checker_event (enum event_kind kind,
137 : : const event_loc_info &loc_info);
138 : :
139 : : public:
140 : : const enum event_kind m_kind;
141 : : protected:
142 : : location_t m_loc;
143 : : tree m_original_fndecl;
144 : : tree m_effective_fndecl;
145 : : int m_original_depth;
146 : : int m_effective_depth;
147 : : pending_diagnostic *m_pending_diagnostic;
148 : : diagnostic_event_id_t m_emission_id; // only set once all pruning has occurred
149 : : tree_logical_location m_logical_loc;
150 : : };
151 : :
152 : : /* A concrete event subclass for a purely textual event, for use in
153 : : debugging path creation and filtering. */
154 : :
155 : : class debug_event : public checker_event
156 : : {
157 : : public:
158 : :
159 : 156 : debug_event (const event_loc_info &loc_info,
160 : : const char *desc)
161 : 156 : : checker_event (EK_DEBUG, loc_info),
162 : 156 : m_desc (xstrdup (desc))
163 : : {
164 : 156 : }
165 : 156 : ~debug_event ()
166 : : {
167 : 156 : free (m_desc);
168 : 156 : }
169 : :
170 : : void print_desc (pretty_printer &) const final override;
171 : :
172 : : private:
173 : : char *m_desc;
174 : : };
175 : :
176 : : /* An abstract event subclass for custom events. These are not filtered,
177 : : as they are likely to be pertinent to the diagnostic. */
178 : :
179 : 20 : class custom_event : public checker_event
180 : : {
181 : : protected:
182 : 597 : custom_event (const event_loc_info &loc_info)
183 : 592 : : checker_event (EK_CUSTOM, loc_info)
184 : : {
185 : : }
186 : : };
187 : :
188 : : /* A concrete custom_event subclass with a precanned message. */
189 : :
190 : : class precanned_custom_event : public custom_event
191 : : {
192 : : public:
193 : 20 : precanned_custom_event (const event_loc_info &loc_info,
194 : : const char *desc)
195 : 20 : : custom_event (loc_info),
196 : 20 : m_desc (xstrdup (desc))
197 : : {
198 : 20 : }
199 : 20 : ~precanned_custom_event ()
200 : : {
201 : 20 : free (m_desc);
202 : 20 : }
203 : :
204 : : void print_desc (pretty_printer &) const final override;
205 : :
206 : : private:
207 : : char *m_desc;
208 : : };
209 : :
210 : : /* A concrete event subclass describing the execution of a gimple statement,
211 : : for use at high verbosity levels when debugging paths. */
212 : :
213 : : class statement_event : public checker_event
214 : : {
215 : : public:
216 : : statement_event (const gimple *stmt, tree fndecl, int depth,
217 : : const program_state &dst_state);
218 : :
219 : : void print_desc (pretty_printer &) const final override;
220 : :
221 : : const gimple * const m_stmt;
222 : : const program_state m_dst_state;
223 : : };
224 : :
225 : : /* An abstract event subclass describing the creation of a region that
226 : : is significant for a diagnostic.
227 : :
228 : : There are too many combinations to express region creation in one message,
229 : : so we emit multiple region_creation_event instances when each pertinent
230 : : region is created.
231 : :
232 : : The events are created by pending_diagnostic's add_region_creation_events
233 : : vfunc, which by default creates a region_creation_event_memory_space, and
234 : : if a capacity is known, a region_creation_event_capacity, giving e.g.:
235 : : (1) region created on stack here
236 : : (2) capacity: 100 bytes
237 : : but this vfunc can be overridden to create other events if other wordings
238 : : are more appropriate foa a given pending_diagnostic. */
239 : :
240 : : class region_creation_event : public checker_event
241 : : {
242 : : protected:
243 : : region_creation_event (const event_loc_info &loc_info);
244 : : };
245 : :
246 : : /* Concrete subclass of region_creation_event.
247 : : Generates a message based on the memory space of the region
248 : : e.g. "region created on stack here". */
249 : :
250 : : class region_creation_event_memory_space : public region_creation_event
251 : : {
252 : : public:
253 : 591 : region_creation_event_memory_space (enum memory_space mem_space,
254 : : const event_loc_info &loc_info)
255 : 591 : : region_creation_event (loc_info),
256 : 591 : m_mem_space (mem_space)
257 : : {
258 : : }
259 : :
260 : : void print_desc (pretty_printer &pp) const final override;
261 : :
262 : : private:
263 : : enum memory_space m_mem_space;
264 : : };
265 : :
266 : : /* Concrete subclass of region_creation_event.
267 : : Generates a message based on the capacity of the region
268 : : e.g. "capacity: 100 bytes". */
269 : :
270 : : class region_creation_event_capacity : public region_creation_event
271 : : {
272 : : public:
273 : 795 : region_creation_event_capacity (tree capacity,
274 : : const event_loc_info &loc_info)
275 : 795 : : region_creation_event (loc_info),
276 : 795 : m_capacity (capacity)
277 : : {
278 : 795 : gcc_assert (m_capacity);
279 : 795 : }
280 : :
281 : : void print_desc (pretty_printer &pp) const final override;
282 : :
283 : : private:
284 : : tree m_capacity;
285 : : };
286 : :
287 : : /* Concrete subclass of region_creation_event.
288 : : Generates a message based on the capacity of the region
289 : : e.g. "allocated 100 bytes here". */
290 : :
291 : : class region_creation_event_allocation_size : public region_creation_event
292 : : {
293 : : public:
294 : 94 : region_creation_event_allocation_size (tree capacity,
295 : : const event_loc_info &loc_info)
296 : 94 : : region_creation_event (loc_info),
297 : 94 : m_capacity (capacity)
298 : : {}
299 : :
300 : : void print_desc (pretty_printer &pp) const final override;
301 : :
302 : : private:
303 : : tree m_capacity;
304 : : };
305 : :
306 : : /* Concrete subclass of region_creation_event.
307 : : Generates a debug message intended for analyzer developers. */
308 : :
309 : : class region_creation_event_debug : public region_creation_event
310 : : {
311 : : public:
312 : 0 : region_creation_event_debug (const region *reg, tree capacity,
313 : : const event_loc_info &loc_info)
314 : 0 : : region_creation_event (loc_info),
315 : 0 : m_reg (reg), m_capacity (capacity)
316 : : {
317 : : }
318 : :
319 : : void print_desc (pretty_printer &pp) const final override;
320 : :
321 : : private:
322 : : const region *m_reg;
323 : : tree m_capacity;
324 : : };
325 : :
326 : : /* An event subclass describing the entry to a function. */
327 : :
328 : 0 : class function_entry_event : public checker_event
329 : : {
330 : : public:
331 : : function_entry_event (const event_loc_info &loc_info)
332 : : : checker_event (EK_FUNCTION_ENTRY, loc_info)
333 : : {
334 : : }
335 : :
336 : : function_entry_event (const program_point &dst_point);
337 : :
338 : : void print_desc (pretty_printer &pp) const override;
339 : : meaning get_meaning () const override;
340 : :
341 : 944 : bool is_function_entry_p () const final override { return true; }
342 : : };
343 : :
344 : : /* Subclass of checker_event describing a state change. */
345 : :
346 : : class state_change_event : public checker_event
347 : : {
348 : : public:
349 : : state_change_event (const supernode *node, const gimple *stmt,
350 : : int stack_depth,
351 : : const state_machine &sm,
352 : : const svalue *sval,
353 : : state_machine::state_t from,
354 : : state_machine::state_t to,
355 : : const svalue *origin,
356 : : const program_state &dst_state,
357 : : const exploded_node *enode);
358 : :
359 : : void print_desc (pretty_printer &pp) const final override;
360 : : meaning get_meaning () const override;
361 : :
362 : 22 : const function *get_dest_function () const
363 : : {
364 : 22 : return m_dst_state.get_current_function ();
365 : : }
366 : :
367 : 164 : const exploded_node *get_exploded_node () const { return m_enode; }
368 : :
369 : : const supernode *m_node;
370 : : const gimple *m_stmt;
371 : : const state_machine &m_sm;
372 : : const svalue *m_sval;
373 : : state_machine::state_t m_from;
374 : : state_machine::state_t m_to;
375 : : const svalue *m_origin;
376 : : program_state m_dst_state;
377 : : const exploded_node *m_enode;
378 : : };
379 : :
380 : : /* Subclass of checker_event; parent class for subclasses that relate to
381 : : a superedge. */
382 : :
383 : 0 : class superedge_event : public checker_event
384 : : {
385 : : public:
386 : : void maybe_add_sarif_properties (sarif_object &thread_flow_loc_obj)
387 : : const override;
388 : :
389 : : /* Mark this edge event as being either an interprocedural call or
390 : : return in which VAR is in STATE, and that this is critical to the
391 : : diagnostic (so that print_desc can attempt to get a better description
392 : : from any pending_diagnostic). */
393 : 261 : void record_critical_state (tree var, state_machine::state_t state)
394 : : {
395 : 261 : m_var = var;
396 : 261 : m_critical_state = state;
397 : 261 : }
398 : :
399 : : const callgraph_superedge& get_callgraph_superedge () const;
400 : :
401 : : bool should_filter_p (int verbosity) const;
402 : :
403 : : protected:
404 : : superedge_event (enum event_kind kind, const exploded_edge &eedge,
405 : : const event_loc_info &loc_info);
406 : :
407 : : public:
408 : : const exploded_edge &m_eedge;
409 : : const superedge *m_sedge;
410 : : tree m_var;
411 : : state_machine::state_t m_critical_state;
412 : : };
413 : :
414 : : /* An abstract event subclass for when a CFG edge is followed; it has two
415 : : subclasses, representing the start of the edge and the end of the
416 : : edge, which come in pairs. */
417 : :
418 : : class cfg_edge_event : public superedge_event
419 : : {
420 : : public:
421 : : meaning get_meaning () const override;
422 : :
423 : : const cfg_superedge& get_cfg_superedge () const;
424 : :
425 : : protected:
426 : : cfg_edge_event (enum event_kind kind, const exploded_edge &eedge,
427 : : const event_loc_info &loc_info);
428 : : };
429 : :
430 : : /* A concrete event subclass for the start of a CFG edge
431 : : e.g. "following 'false' branch...'. */
432 : :
433 : : class start_cfg_edge_event : public cfg_edge_event
434 : : {
435 : : public:
436 : 10642 : start_cfg_edge_event (const exploded_edge &eedge,
437 : : const event_loc_info &loc_info)
438 : 10642 : : cfg_edge_event (EK_START_CFG_EDGE, eedge, loc_info)
439 : : {
440 : : }
441 : :
442 : : void print_desc (pretty_printer &pp) const override;
443 : 482 : bool connect_to_next_event_p () const final override { return true; }
444 : :
445 : : protected:
446 : : label_text maybe_describe_condition (bool can_colorize) const;
447 : :
448 : : private:
449 : : static label_text maybe_describe_condition (bool can_colorize,
450 : : tree lhs,
451 : : enum tree_code op,
452 : : tree rhs);
453 : : static bool should_print_expr_p (tree);
454 : : };
455 : :
456 : : /* A concrete event subclass for the end of a CFG edge
457 : : e.g. "...to here'. */
458 : :
459 : : class end_cfg_edge_event : public cfg_edge_event
460 : : {
461 : : public:
462 : 10642 : end_cfg_edge_event (const exploded_edge &eedge,
463 : : const event_loc_info &loc_info)
464 : 10642 : : cfg_edge_event (EK_END_CFG_EDGE, eedge, loc_info)
465 : : {
466 : : }
467 : :
468 : 4900 : void print_desc (pretty_printer &pp) const final override
469 : : {
470 : 4900 : pp_string (&pp, "...to here");
471 : 4900 : }
472 : : };
473 : :
474 : : /* A concrete event subclass for an interprocedural call. */
475 : :
476 : 0 : class call_event : public superedge_event
477 : : {
478 : : public:
479 : : call_event (const exploded_edge &eedge,
480 : : const event_loc_info &loc_info);
481 : :
482 : : void print_desc (pretty_printer &pp) const override;
483 : : meaning get_meaning () const override;
484 : :
485 : : bool is_call_p () const final override;
486 : :
487 : : protected:
488 : : tree get_caller_fndecl () const;
489 : : tree get_callee_fndecl () const;
490 : :
491 : : const supernode *m_src_snode;
492 : : const supernode *m_dest_snode;
493 : : };
494 : :
495 : : /* A concrete event subclass for an interprocedural return. */
496 : :
497 : : class return_event : public superedge_event
498 : : {
499 : : public:
500 : : return_event (const exploded_edge &eedge,
501 : : const event_loc_info &loc_info);
502 : :
503 : : void print_desc (pretty_printer &pp) const final override;
504 : : meaning get_meaning () const override;
505 : :
506 : : bool is_return_p () const final override;
507 : :
508 : : const supernode *m_src_snode;
509 : : const supernode *m_dest_snode;
510 : : };
511 : :
512 : : /* A concrete event subclass for the start of a consolidated run of CFG
513 : : edges all either TRUE or FALSE e.g. "following 'false' branch...'. */
514 : :
515 : : class start_consolidated_cfg_edges_event : public checker_event
516 : : {
517 : : public:
518 : 67 : start_consolidated_cfg_edges_event (const event_loc_info &loc_info,
519 : : bool edge_sense)
520 : 67 : : checker_event (EK_START_CONSOLIDATED_CFG_EDGES, loc_info),
521 : 67 : m_edge_sense (edge_sense)
522 : : {
523 : : }
524 : :
525 : : void print_desc (pretty_printer &pp) const final override;
526 : : meaning get_meaning () const override;
527 : 0 : bool connect_to_next_event_p () const final override { return true; }
528 : :
529 : : private:
530 : : bool m_edge_sense;
531 : : };
532 : :
533 : : /* A concrete event subclass for the end of a consolidated run of
534 : : CFG edges e.g. "...to here'. */
535 : :
536 : : class end_consolidated_cfg_edges_event : public checker_event
537 : : {
538 : : public:
539 : 67 : end_consolidated_cfg_edges_event (const event_loc_info &loc_info)
540 : 67 : : checker_event (EK_END_CONSOLIDATED_CFG_EDGES, loc_info)
541 : : {
542 : : }
543 : :
544 : 117 : void print_desc (pretty_printer &pp) const final override
545 : : {
546 : 117 : pp_string (&pp, "...to here");
547 : 117 : }
548 : : };
549 : :
550 : : /* A concrete event subclass for describing an inlined call event
551 : : e.g. "inlined call to 'callee' from 'caller'". */
552 : :
553 : : class inlined_call_event : public checker_event
554 : : {
555 : : public:
556 : 170 : inlined_call_event (location_t loc,
557 : : tree apparent_callee_fndecl,
558 : : tree apparent_caller_fndecl,
559 : : int actual_depth,
560 : : int stack_depth_adjustment)
561 : 170 : : checker_event (EK_INLINED_CALL,
562 : 170 : event_loc_info (loc,
563 : : apparent_caller_fndecl,
564 : 170 : actual_depth + stack_depth_adjustment)),
565 : 170 : m_apparent_callee_fndecl (apparent_callee_fndecl),
566 : 170 : m_apparent_caller_fndecl (apparent_caller_fndecl)
567 : : {
568 : 170 : gcc_assert (LOCATION_BLOCK (loc) == NULL);
569 : 170 : }
570 : :
571 : : void print_desc (pretty_printer &) const final override;
572 : : meaning get_meaning () const override;
573 : :
574 : : private:
575 : : tree m_apparent_callee_fndecl;
576 : : tree m_apparent_caller_fndecl;
577 : : };
578 : :
579 : : /* A concrete event subclass for a setjmp or sigsetjmp call. */
580 : :
581 : : class setjmp_event : public checker_event
582 : : {
583 : : public:
584 : 20 : setjmp_event (const event_loc_info &loc_info,
585 : : const exploded_node *enode,
586 : : const gcall *setjmp_call)
587 : 20 : : checker_event (EK_SETJMP, loc_info),
588 : 20 : m_enode (enode), m_setjmp_call (setjmp_call)
589 : : {
590 : : }
591 : :
592 : : void print_desc (pretty_printer &pp) const final override;
593 : :
594 : : void prepare_for_emission (checker_path *path,
595 : : pending_diagnostic *pd,
596 : : diagnostic_event_id_t emission_id) final override;
597 : :
598 : : private:
599 : : const exploded_node *m_enode;
600 : : const gcall *m_setjmp_call;
601 : : };
602 : :
603 : : /* An abstract event subclass for rewinding from a longjmp to a setjmp
604 : : (or siglongjmp to sigsetjmp).
605 : :
606 : : Base class for two from/to subclasses, showing the two halves of the
607 : : rewind. */
608 : :
609 : : class rewind_event : public checker_event
610 : : {
611 : : public:
612 : : tree get_longjmp_caller () const;
613 : : tree get_setjmp_caller () const;
614 : : const exploded_edge *get_eedge () const { return m_eedge; }
615 : :
616 : : protected:
617 : : rewind_event (const exploded_edge *eedge,
618 : : enum event_kind kind,
619 : : const event_loc_info &loc_info,
620 : : const rewind_info_t *rewind_info);
621 : : const rewind_info_t *m_rewind_info;
622 : :
623 : : private:
624 : : const exploded_edge *m_eedge;
625 : : };
626 : :
627 : : /* A concrete event subclass for rewinding from a longjmp to a setjmp,
628 : : showing the longjmp (or siglongjmp). */
629 : :
630 : : class rewind_from_longjmp_event : public rewind_event
631 : : {
632 : : public:
633 : 15 : rewind_from_longjmp_event (const exploded_edge *eedge,
634 : : const event_loc_info &loc_info,
635 : : const rewind_info_t *rewind_info)
636 : 15 : : rewind_event (eedge, EK_REWIND_FROM_LONGJMP, loc_info,
637 : 15 : rewind_info)
638 : : {
639 : : }
640 : :
641 : : void print_desc (pretty_printer &pp) const final override;
642 : : };
643 : :
644 : : /* A concrete event subclass for rewinding from a longjmp to a setjmp,
645 : : showing the setjmp (or sigsetjmp). */
646 : :
647 : : class rewind_to_setjmp_event : public rewind_event
648 : : {
649 : : public:
650 : 15 : rewind_to_setjmp_event (const exploded_edge *eedge,
651 : : const event_loc_info &loc_info,
652 : : const rewind_info_t *rewind_info)
653 : 15 : : rewind_event (eedge, EK_REWIND_TO_SETJMP, loc_info,
654 : 15 : rewind_info)
655 : : {
656 : : }
657 : :
658 : : void print_desc (pretty_printer &pp) const final override;
659 : :
660 : : void prepare_for_emission (checker_path *path,
661 : : pending_diagnostic *pd,
662 : : diagnostic_event_id_t emission_id) final override;
663 : :
664 : : private:
665 : : diagnostic_event_id_t m_original_setjmp_event_id;
666 : : };
667 : :
668 : : /* Concrete subclass of checker_event for use at the end of a path:
669 : : a repeat of the warning message at the end of the path (perhaps with
670 : : references to pertinent events that occurred on the way), at the point
671 : : where the problem occurs. */
672 : :
673 : : class warning_event : public checker_event
674 : : {
675 : : public:
676 : 3849 : warning_event (const event_loc_info &loc_info,
677 : : const exploded_node *enode,
678 : : const state_machine *sm,
679 : : tree var, state_machine::state_t state)
680 : 3849 : : checker_event (EK_WARNING, loc_info),
681 : 3849 : m_enode (enode),
682 : 3849 : m_sm (sm), m_var (var), m_state (state)
683 : : {
684 : : }
685 : :
686 : : void print_desc (pretty_printer &pp) const final override;
687 : : meaning get_meaning () const override;
688 : :
689 : 164 : const exploded_node *get_exploded_node () const { return m_enode; }
690 : :
691 : : private:
692 : : const exploded_node *m_enode;
693 : : const state_machine *m_sm;
694 : : tree m_var;
695 : : state_machine::state_t m_state;
696 : : };
697 : :
698 : : } // namespace ana
699 : :
700 : : #endif /* GCC_ANALYZER_CHECKER_EVENT_H */
|