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