GCC Middle and Back End API Reference
pending-diagnostic.h
Go to the documentation of this file.
1/* Classes for analyzer diagnostics.
2 Copyright (C) 2019-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#ifndef GCC_ANALYZER_PENDING_DIAGNOSTIC_H
22#define GCC_ANALYZER_PENDING_DIAGNOSTIC_H
23
25#include "analyzer/sm.h"
27
28namespace ana {
29
30/* A bundle of information about things that are of interest to a
31 pending_diagnostic:
32
33 * a set of regions that are pertinent to the
34 diagnostic, so that we can notify the user about when they
35 were created.
36
37 * a set of regions that a pertinent value for the diagnostic was
38 read from, so that we can notify the user about where those values
39 came from. */
40
42{
43 void add_region_creation (const region *reg);
44
45 void add_read_region (const region *reg, std::string debug_desc);
46
47 void dump_to_pp (pretty_printer *pp, bool simple) const;
48
50 std::vector<diagnostic_state> m_read_regions;
51};
52
53/* Various bundles of information used for generating more precise
54 messages for events within a diagnostic path, for passing to the
55 various "describe_*" vfuncs of pending_diagnostic. See those
56 for more information. */
57
58namespace evdesc {
59
60/* For use by pending_diagnostic::describe_state_change. */
61
84
85/* For use by pending_diagnostic::describe_origin_of_state. */
86
88{
89 origin_of_state (tree dst_reg_expr)
90 : m_dst_reg_expr (dst_reg_expr)
91 {
93 }
94
96};
97
98/* For use by pending_diagnostic::describe_call_with_state. */
99
101{
102 call_with_state (tree caller_fndecl, tree callee_fndecl,
104 const state_transition_at_call *state_trans)
105 : m_caller_fndecl (caller_fndecl),
106 m_callee_fndecl (callee_fndecl),
107 m_expr (expr),
108 m_state (state),
109 m_state_trans (state_trans)
110 {
111 if (state_trans)
112 m_src_event_id = state_trans->get_src_event_id ();
113 }
114
121};
122
123/* For use by pending_diagnostic::describe_return_of_state. */
124
126{
127 return_of_state (tree caller_fndecl, tree callee_fndecl,
129 const state_transition_at_return *state_trans)
130 : m_caller_fndecl (caller_fndecl),
131 m_callee_fndecl (callee_fndecl),
132 m_state (state),
133 m_state_trans (state_trans)
134 {
135 if (state_trans)
136 m_src_event_id = state_trans->get_src_event_id ();
137 }
138
144};
145
146/* For use by pending_diagnostic::describe_copy_of_state. */
147
149{
150 copy_of_state (tree src_reg_expr,
152 tree dst_reg_expr)
153 : m_src_reg_expr (src_reg_expr),
154 m_src_event_id (src_event_id),
155 m_dst_reg_expr (dst_reg_expr)
156 {
159 }
160
164};
165
166/* For use by pending_diagnostic::describe_use_of_state. */
167
169{
170 use_of_state (tree src_reg_expr,
172 : m_src_reg_expr (src_reg_expr),
173 m_src_event_id (src_event_id)
174 {
176 }
177
180};
181
182/* For use by pending_diagnostic::describe_final_event. */
183
195
196} /* end of namespace evdesc */
197
198/* A bundle of information for use by implementations of the
199 pending_diagnostic::emit vfunc.
200
201 The rich_location will have already been populated with a
202 diagnostics::paths::path. */
203
205{
206public:
208 rich_location &rich_loc,
209 diagnostics::metadata &metadata,
210 logger *logger)
211 : m_sd (sd),
212 m_rich_loc (rich_loc),
213 m_metadata (metadata),
215 {
216 }
217
219
220 bool warn (const char *, ...) ATTRIBUTE_GCC_DIAG (2,3);
221 void inform (const char *, ...) ATTRIBUTE_GCC_DIAG (2,3);
222
223 location_t get_location () const { return m_rich_loc.get_loc (); }
224 logger *get_logger () const { return m_logger; }
225
226 void add_cwe (int cwe) { m_metadata.add_cwe (cwe); }
228 {
230 }
231
232private:
234 rich_location &m_rich_loc;
237};
238
239/* An abstract base class for capturing information about a diagnostic in
240 a form that is ready to emit at a later point (or be rejected).
241 Each kind of diagnostic will have a concrete subclass of
242 pending_diagnostic.
243
244 Normally, gcc diagnostics are emitted using va_list, which can't be
245 portably stored for later use, so we have to use an "emit" virtual
246 function.
247
248 This class also supports comparison, so that multiple pending_diagnostic
249 instances can be de-duplicated.
250
251 As well as emitting a diagnostic, the class has various "precision of
252 wording" virtual functions, for generating descriptions for events
253 within a diagnostic path. These are optional, but implementing these
254 allows for more precise wordings than the more generic
255 implementation. */
256
258{
259 public:
261
262 /* Vfunc to get the command-line option used when emitting the diagnostic,
263 or zero if there is none.
264 Used by diagnostic_manager for early rejection of diagnostics (to avoid
265 having to generate feasible execution paths for them). */
266 virtual int get_controlling_option () const = 0;
267
268 /* Vfunc to give the diagnostic the chance to terminate the execution
269 path being explored. By default, don't terminate the path. */
270 virtual bool terminate_path_p () const { return false; }
271
272 /* Vfunc for emitting the diagnostic.
273 Return true if a diagnostic is actually emitted. */
274 virtual bool emit (diagnostic_emission_context &) = 0;
275
276 /* Hand-coded RTTI: get an ID for the subclass. */
277 virtual const char *get_kind () const = 0;
278
279 virtual std::unique_ptr<json::object> to_json () const;
280
281 /* A vfunc for identifying "use of uninitialized value". */
282 virtual bool use_of_uninit_p () const { return false; }
283
284 /* Compare for equality with OTHER, which might be of a different
285 subclass. */
286
287 bool equal_p (const pending_diagnostic &other) const
288 {
289 /* Check for pointer equality on the IDs from get_kind. */
290 if (get_kind () != other.get_kind ())
291 return false;
292 /* Call vfunc now we know they have the same ID: */
293 return subclass_equal_p (other);
294 }
295
296 /* A vfunc for testing for equality, where we've already
297 checked they have the same ID. See pending_diagnostic_subclass
298 below for a convenience subclass for implementing this. */
299 virtual bool subclass_equal_p (const pending_diagnostic &other) const = 0;
300
301 /* Return true if T1 and T2 are "the same" for the purposes of
302 diagnostic deduplication. */
303 static bool same_tree_p (tree t1, tree t2);
304
305 /* Vfunc for fixing up locations, e.g. to avoid unwinding
306 inside specific macros. PRIMARY is true for the primary location
307 for the diagnostic, and FALSE for events in their paths. */
308 virtual location_t fixup_location (location_t loc, bool primary) const;
309
310 /* Precision-of-wording vfunc for describing a critical state change
311 within the diagnostic path.
312
313 For example, a double-free diagnostic might use the descriptions:
314 - "first 'free' happens here"
315 - "second 'free' happens here"
316 for the pertinent events, whereas a use-after-free might use the
317 descriptions:
318 - "freed here"
319 - "use after free here"
320 Note how in both cases the first event is a "free": the best
321 description to use depends on the diagnostic.
322
323 Print the description to PP and return true,
324 or do nothing and return false. */
325
327 const evdesc::state_change &)
328 {
329 /* Default no-op implementation. */
330 return false;
331 }
332
333 /* Vfunc for implementing event::get_meaning for
334 state_change_event. */
337 {
338 /* Default no-op implementation. */
340 }
341
342 /* Precision-of-wording vfunc for use in describing state_transition_event
343 instances of state_transition::kind::origin.
344 Return true if a description of the event was printed to the
345 pretty-printer, or false otherwise.
346 For example, a divide-by-zero diagnostic might use:
347 "zero value originates here"
348 at the point where the zero comes from. */
351 {
352 /* Default no-op implementation. */
353 return false;
354 }
355
356 /* Precision-of-wording vfunc for describing an interprocedural call
357 carrying critical state for the diagnostic, from caller to callee.
358
359 For example a double-free diagnostic might use:
360 - "passing freed pointer 'ptr' in call to 'deallocator' from 'test'"
361 to make it clearer how the freed value moves from caller to
362 callee. */
363
366 {
367 /* Default no-op implementation. */
368 return false;
369 }
370
371 /* Precision-of-wording vfunc for describing an interprocedural return
372 within the diagnostic path that carries critical state for the
373 diagnostic, from callee back to caller.
374
375 For example, a deref-of-unchecked-malloc diagnostic might use:
376 - "returning possibly-NULL pointer to 'make_obj' from 'allocator'"
377 to make it clearer how the unchecked value moves from callee
378 back to caller. */
379
382 {
383 /* Default no-op implementation. */
384 return false;
385 }
386
387 /* Precision-of-wording vfunc for use in describing state_transition_event
388 instances of state_transition::kind::copy.
389 Return true if a description of the event was printed to the
390 pretty-printer, or false otherwise.
391 For example, a divide-by-zero diagnostic might use:
392 "copying zero value from (3) from 'x' to 'y'". */
394 const evdesc::copy_of_state &)
395 {
396 /* Default no-op implementation. */
397 return false;
398 }
399
400 /* Precision-of-wording vfunc for use in describing state_transition_event
401 instances of state_transition::kind::use.
402 Return true if a description of the event was printed to the
403 pretty-printer, or false otherwise.
404 For example, a divide-by-zero diagnostic might use:
405 "using zero value from (7) from 'y'". */
407 const evdesc::use_of_state &)
408 {
409 /* Default no-op implementation. */
410 return false;
411 }
412
413 /* Precision-of-wording vfunc for describing the final event within a
414 diagnostic path.
415
416 For example a double-free diagnostic might use:
417 - "second 'free' here; first 'free' was at (3)"
418 and a use-after-free might use
419 - "use after 'free' here; memory was freed at (2)". */
420
422 const evdesc::final_event &)
423 {
424 /* Default no-op implementation. */
425 return false;
426 }
427
428 /* End of precision-of-wording vfuncs. */
429
430 /* Vfunc for adding a function_entry_event to a checker_path, so that e.g.
431 the infinite recursion diagnostic can add a custom event subclass
432 that annotates recursively entering a function. */
433
434 virtual void
436 checker_path *emission_path,
437 const state_transition_at_call *state_trans);
438
439 /* Vfunc for extending/overriding creation of the events for an
440 exploded_edge, allowing for custom events to be created that are
441 pertinent to a particular pending_diagnostic subclass.
442
443 For example, the -Wanalyzer-stale-setjmp-buffer diagnostic adds a
444 custom event showing when the pertinent stack frame is popped
445 (and thus the point at which the jmp_buf becomes invalid). */
446
448 checker_path *)
449 {
450 return false;
451 }
452
453 /* Vfunc for adding a call_event to a checker_path, so that e.g.
454 the varargs diagnostics can add a custom event subclass that annotates
455 the variadic arguments. */
456 virtual void add_call_event (const exploded_edge &,
457 const gcall &call_stmt,
458 checker_path &emission_path,
459 const state_transition_at_call *state_trans);
460
461 /* Vfunc for adding any events for the creation of regions identified
462 by the mark_interesting_stuff vfunc.
463 See the comment for class region_creation_event. */
464 virtual void add_region_creation_events (const region *reg,
465 tree capacity,
466 const event_loc_info &loc_info,
467 checker_path &emission_path);
468
469 /* Vfunc for adding the final warning_event to a checker_path, so that e.g.
470 the infinite recursion diagnostic can have its diagnostic appear at
471 the callsite, but the final event in the path be at the entrypoint
472 of the called function. */
473 virtual void add_final_event (const state_machine *sm,
474 const exploded_node *enode,
475 const event_loc_info &loc_info,
477 checker_path *emission_path);
478
479 virtual const program_state *
481 {
482 return nullptr;
483 }
484
485 /* Vfunc for determining that this pending_diagnostic supercedes OTHER,
486 and that OTHER should therefore not be emitted.
487 They have already been tested for being at the same stmt. */
488
489 virtual bool
490 supercedes_p (const pending_diagnostic &other ATTRIBUTE_UNUSED) const
491 {
492 return false;
493 }
494
495 /* Vfunc for registering additional information of interest to this
496 diagnostic. */
497
499 {
500 /* Default no-op implementation. */
501 }
502
503 /* Vfunc to give diagnostic subclasses the opportunity to reject diagnostics
504 by imposing their own additional feasibility checks on the path to a
505 given feasible_node. */
506 virtual bool check_valid_fpath_p (const feasible_node &) const
507 {
508 /* Default implementation: accept this path. */
509 return true;
510 }
511
512 /* Vfunc for use in SARIF output to give pending_diagnostic subclasses
513 the opportunity to add diagnostic-specific properties to the SARIF
514 "result" object for the diagnostic.
515 This is intended for use when debugging a diagnostic. */
516 virtual void
518 {
519 /* Default no-op implementation. */
520 }
521};
522
523/* A template to make it easier to make subclasses of pending_diagnostic.
524
525 This uses the curiously-recurring template pattern, to implement
526 pending_diagnostic::subclass_equal_p by casting and calling
527 the operator==
528
529 This assumes that BASE_OTHER has already been checked to have
530 been of the same subclass (which pending_diagnostic::equal_p does). */
531
532template <class Subclass>
534{
535 public:
536 bool subclass_equal_p (const pending_diagnostic &base_other) const
537 final override
538 {
539 const Subclass &other = (const Subclass &)base_other;
540 return *(const Subclass*)this == other;
541 }
542};
543
544/* An abstract base class for capturing additional notes that are to be
545 emitted with a diagnostic. */
546
548{
549public:
550 virtual ~pending_note () {}
551
552 /* Hand-coded RTTI: get an ID for the subclass. */
553 virtual const char *get_kind () const = 0;
554
555 /* Vfunc for emitting the note. */
556 virtual void emit () const = 0;
557
558 bool equal_p (const pending_note &other) const
559 {
560 /* Check for pointer equality on the IDs from get_kind. */
561 if (get_kind () != other.get_kind ())
562 return false;
563 /* Call vfunc now we know they have the same ID: */
564 return subclass_equal_p (other);
565 }
566
567 /* A vfunc for testing for equality, where we've already
568 checked they have the same ID. See pending_note_subclass
569 below for a convenience subclass for implementing this. */
570 virtual bool subclass_equal_p (const pending_note &other) const = 0;
571};
572
573/* Analogous to pending_diagnostic_subclass, but for pending_note. */
574
575template <class Subclass>
577{
578 public:
579 bool subclass_equal_p (const pending_note &base_other) const
580 final override
581 {
582 const Subclass &other = (const Subclass &)base_other;
583 return *(const Subclass*)this == other;
584 }
585};
586
587} // namespace ana
588
589#endif /* GCC_ANALYZER_PENDING_DIAGNOSTIC_H */
Definition checker-path.h:32
Definition pending-diagnostic.h:205
const saved_diagnostic & m_sd
Definition pending-diagnostic.h:233
void add_rule(const diagnostics::metadata::rule &r)
Definition pending-diagnostic.h:227
diagnostics::metadata & m_metadata
Definition pending-diagnostic.h:235
bool warn(const char *,...) ATTRIBUTE_GCC_DIAG(2
rich_location & m_rich_loc
Definition pending-diagnostic.h:234
bool void inform(const char *,...) ATTRIBUTE_GCC_DIAG(2
void add_cwe(int cwe)
Definition pending-diagnostic.h:226
logger * m_logger
Definition pending-diagnostic.h:236
logger * get_logger() const
Definition pending-diagnostic.h:224
diagnostic_emission_context(const saved_diagnostic &sd, rich_location &rich_loc, diagnostics::metadata &metadata, logger *logger)
Definition pending-diagnostic.h:207
bool void location_t get_location() const
Definition pending-diagnostic.h:223
const pending_diagnostic & get_pending_diagnostic() const
Definition exploded-graph.h:347
Definition exploded-graph.h:221
Definition feasible-graph.h:84
Definition analyzer-logging.h:36
Definition pending-diagnostic.h:534
bool subclass_equal_p(const pending_diagnostic &base_other) const final override
Definition pending-diagnostic.h:536
Definition pending-diagnostic.h:258
virtual bool describe_origin_of_state(pretty_printer &, const evdesc::origin_of_state &)
Definition pending-diagnostic.h:349
virtual bool describe_final_event(pretty_printer &, const evdesc::final_event &)
Definition pending-diagnostic.h:421
virtual bool describe_return_of_state(pretty_printer &, const evdesc::return_of_state &)
Definition pending-diagnostic.h:380
virtual diagnostics::paths::event::meaning get_meaning_for_state_change(const evdesc::state_change &) const
Definition pending-diagnostic.h:336
virtual bool describe_use_of_state(pretty_printer &, const evdesc::use_of_state &)
Definition pending-diagnostic.h:406
virtual ~pending_diagnostic()
Definition pending-diagnostic.h:260
virtual void maybe_add_sarif_properties(diagnostics::sarif_object &) const
Definition pending-diagnostic.h:517
virtual bool use_of_uninit_p() const
Definition pending-diagnostic.h:282
virtual const program_state * get_final_state() const
Definition pending-diagnostic.h:480
virtual std::unique_ptr< json::object > to_json() const
virtual bool describe_call_with_state(pretty_printer &, const evdesc::call_with_state &)
Definition pending-diagnostic.h:364
virtual bool subclass_equal_p(const pending_diagnostic &other) const =0
virtual bool maybe_add_custom_events_for_eedge(const exploded_edge &, checker_path *)
Definition pending-diagnostic.h:447
virtual void mark_interesting_stuff(interesting_t *)
Definition pending-diagnostic.h:498
virtual bool describe_state_change(pretty_printer &, const evdesc::state_change &)
Definition pending-diagnostic.h:326
virtual void add_call_event(const exploded_edge &, const gcall &call_stmt, checker_path &emission_path, const state_transition_at_call *state_trans)
virtual void add_region_creation_events(const region *reg, tree capacity, const event_loc_info &loc_info, checker_path &emission_path)
virtual bool describe_copy_of_state(pretty_printer &, const evdesc::copy_of_state &)
Definition pending-diagnostic.h:393
virtual const char * get_kind() const =0
virtual bool check_valid_fpath_p(const feasible_node &) const
Definition pending-diagnostic.h:506
virtual bool terminate_path_p() const
Definition pending-diagnostic.h:270
virtual bool supercedes_p(const pending_diagnostic &other) const
Definition pending-diagnostic.h:490
bool equal_p(const pending_diagnostic &other) const
Definition pending-diagnostic.h:287
virtual void add_final_event(const state_machine *sm, const exploded_node *enode, const event_loc_info &loc_info, tree var, state_machine::state_t state, checker_path *emission_path)
virtual int get_controlling_option() const =0
static bool same_tree_p(tree t1, tree t2)
virtual bool emit(diagnostic_emission_context &)=0
virtual void add_function_entry_event(const exploded_edge &eedge, checker_path *emission_path, const state_transition_at_call *state_trans)
virtual location_t fixup_location(location_t loc, bool primary) const
Definition pending-diagnostic.h:577
bool subclass_equal_p(const pending_note &base_other) const final override
Definition pending-diagnostic.h:579
Definition pending-diagnostic.h:548
virtual ~pending_note()
Definition pending-diagnostic.h:550
virtual bool subclass_equal_p(const pending_note &other) const =0
virtual void emit() const =0
virtual const char * get_kind() const =0
bool equal_p(const pending_note &other) const
Definition pending-diagnostic.h:558
Definition program-state.h:224
Definition region.h:127
Definition diagnostic-manager.h:79
Definition checker-event.h:417
Definition sm.h:43
const state_machine::state * state_t
Definition sm.h:63
Definition state-transition.h:99
Definition state-transition.h:126
diagnostics::paths::event_id_t get_src_event_id() const
Definition checker-event.h:931
Definition vec.h:1667
Definition metadata.h:48
Definition metadata.h:41
void add_rule(const rule &r)
Definition metadata.h:92
void add_cwe(int cwe)
Definition metadata.h:87
Definition sarif-sink.h:151
Definition genmatch.cc:1625
Definition pretty-print.h:241
union tree_node * tree
Definition coretypes.h:97
#define ATTRIBUTE_GCC_DIAG(m, n)
Definition diagnostic-core.h:71
Definition pending-diagnostic.h:58
Definition access-diagram.h:30
diagnostic_event_id_t event_id_t
Definition event-id.h:66
poly_int< N, C > r
Definition poly-int.h:774
Definition pending-diagnostic.h:101
diagnostics::paths::event_id_t m_src_event_id
Definition pending-diagnostic.h:120
tree m_caller_fndecl
Definition pending-diagnostic.h:115
const state_transition_at_call * m_state_trans
Definition pending-diagnostic.h:119
tree m_callee_fndecl
Definition pending-diagnostic.h:116
call_with_state(tree caller_fndecl, tree callee_fndecl, tree expr, state_machine::state_t state, const state_transition_at_call *state_trans)
Definition pending-diagnostic.h:102
state_machine::state_t m_state
Definition pending-diagnostic.h:118
tree m_expr
Definition pending-diagnostic.h:117
Definition pending-diagnostic.h:149
copy_of_state(tree src_reg_expr, diagnostics::paths::event_id_t src_event_id, tree dst_reg_expr)
Definition pending-diagnostic.h:150
diagnostics::paths::event_id_t m_src_event_id
Definition pending-diagnostic.h:162
tree m_src_reg_expr
Definition pending-diagnostic.h:161
tree m_dst_reg_expr
Definition pending-diagnostic.h:163
Definition pending-diagnostic.h:185
state_machine::state_t m_state
Definition pending-diagnostic.h:192
final_event(tree expr, state_machine::state_t state, const warning_event &event)
Definition pending-diagnostic.h:186
const warning_event & m_event
Definition pending-diagnostic.h:193
tree m_expr
Definition pending-diagnostic.h:191
Definition pending-diagnostic.h:88
origin_of_state(tree dst_reg_expr)
Definition pending-diagnostic.h:89
tree m_dst_reg_expr
Definition pending-diagnostic.h:95
Definition pending-diagnostic.h:126
const state_transition_at_return * m_state_trans
Definition pending-diagnostic.h:142
diagnostics::paths::event_id_t m_src_event_id
Definition pending-diagnostic.h:143
tree m_callee_fndecl
Definition pending-diagnostic.h:140
state_machine::state_t m_state
Definition pending-diagnostic.h:141
tree m_caller_fndecl
Definition pending-diagnostic.h:139
return_of_state(tree caller_fndecl, tree callee_fndecl, state_machine::state_t state, const state_transition_at_return *state_trans)
Definition pending-diagnostic.h:127
Definition pending-diagnostic.h:63
diagnostics::paths::event_id_t m_event_id
Definition pending-diagnostic.h:81
tree m_expr
Definition pending-diagnostic.h:77
state_machine::state_t m_old_state
Definition pending-diagnostic.h:79
const state_change_event & m_event
Definition pending-diagnostic.h:82
bool is_global_p() const
Definition pending-diagnostic.h:75
state_change(tree expr, tree origin, state_machine::state_t old_state, state_machine::state_t new_state, diagnostics::paths::event_id_t event_id, const state_change_event &event)
Definition pending-diagnostic.h:64
state_machine::state_t m_new_state
Definition pending-diagnostic.h:80
tree m_origin
Definition pending-diagnostic.h:78
Definition pending-diagnostic.h:169
diagnostics::paths::event_id_t m_src_event_id
Definition pending-diagnostic.h:179
tree m_src_reg_expr
Definition pending-diagnostic.h:178
use_of_state(tree src_reg_expr, diagnostics::paths::event_id_t src_event_id)
Definition pending-diagnostic.h:170
Definition event-loc-info.h:29
Definition pending-diagnostic.h:42
std::vector< diagnostic_state > m_read_regions
Definition pending-diagnostic.h:50
void dump_to_pp(pretty_printer *pp, bool simple) const
void add_region_creation(const region *reg)
void add_read_region(const region *reg, std::string debug_desc)
auto_vec< const region * > m_region_creation
Definition pending-diagnostic.h:49
Definition gimple.h:355
Definition genautomata.cc:669
#define gcc_assert(EXPR)
Definition system.h:772
#define NULL_TREE
Definition tree.h:318