]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/analyzer/analyzer.cc
Initial commit of analyzer
[thirdparty/gcc.git] / gcc / analyzer / analyzer.cc
CommitLineData
757bf1df
DM
1/* Utility functions for the analyzer.
2 Copyright (C) 2019-2020 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 "config.h"
22#include "system.h"
23#include "coretypes.h"
24#include "tree.h"
25#include "function.h"
26#include "basic-block.h"
27#include "gimple.h"
28#include "diagnostic.h"
29#include "intl.h"
30#include "function.h"
31#include "analyzer/analyzer.h"
32
33#if ENABLE_ANALYZER
34
35/* Helper function for checkers. Is the CALL to the given function name,
36 and with the given number of arguments?
37
38 This doesn't resolve function pointers via the region model;
39 is_named_call_p should be used instead, using a fndecl from
40 get_fndecl_for_call; this function should only be used for special cases
41 where it's not practical to get at the region model, or for special
42 analyzer functions such as __analyzer_dump. */
43
44bool
45is_special_named_call_p (const gcall *call, const char *funcname,
46 unsigned int num_args)
47{
48 gcc_assert (funcname);
49
50 tree fndecl = gimple_call_fndecl (call);
51 if (!fndecl)
52 return false;
53
54 return is_named_call_p (fndecl, funcname, call, num_args);
55}
56
57/* Helper function for checkers. Does FNDECL have the given FUNCNAME? */
58
59bool
60is_named_call_p (tree fndecl, const char *funcname)
61{
62 gcc_assert (fndecl);
63 gcc_assert (funcname);
64
65 return 0 == strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), funcname);
66}
67
68/* Helper function for checkers. Does FNDECL have the given FUNCNAME, and
69 does CALL have the given number of arguments? */
70
71bool
72is_named_call_p (tree fndecl, const char *funcname,
73 const gcall *call, unsigned int num_args)
74{
75 gcc_assert (fndecl);
76 gcc_assert (funcname);
77
78 if (!is_named_call_p (fndecl, funcname))
79 return false;
80
81 if (gimple_call_num_args (call) != num_args)
82 return false;
83
84 return true;
85}
86
87/* Return true if stmt is a setjmp call. */
88
89bool
90is_setjmp_call_p (const gimple *stmt)
91{
92 /* TODO: is there a less hacky way to check for "setjmp"? */
93 if (const gcall *call = dyn_cast <const gcall *> (stmt))
94 if (is_special_named_call_p (call, "_setjmp", 1))
95 return true;
96
97 return false;
98}
99
100/* Return true if stmt is a longjmp call. */
101
102bool
103is_longjmp_call_p (const gcall *call)
104{
105 /* TODO: is there a less hacky way to check for "longjmp"? */
106 if (is_special_named_call_p (call, "longjmp", 2))
107 return true;
108
109 return false;
110}
111
112/* Generate a label_text instance by formatting FMT, using a
113 temporary clone of the global_dc's printer (thus using its
114 formatting callbacks).
115
116 Colorize if the global_dc supports colorization and CAN_COLORIZE is
117 true. */
118
119label_text
120make_label_text (bool can_colorize, const char *fmt, ...)
121{
122 pretty_printer *pp = global_dc->printer->clone ();
123 pp_clear_output_area (pp);
124
125 if (!can_colorize)
126 pp_show_color (pp) = false;
127
128 text_info ti;
129 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
130
131 va_list ap;
132
133 va_start (ap, fmt);
134
135 ti.format_spec = _(fmt);
136 ti.args_ptr = &ap;
137 ti.err_no = 0;
138 ti.x_data = NULL;
139 ti.m_richloc = &rich_loc;
140
141 pp_format (pp, &ti);
142 pp_output_formatted_text (pp);
143
144 va_end (ap);
145
146 label_text result = label_text::take (xstrdup (pp_formatted_text (pp)));
147 delete pp;
148 return result;
149}
150
151#endif /* #if ENABLE_ANALYZER */