selftest.h revision 1.1.1.1.4.2 1 1.1.1.1.4.2 martin /* A self-testing framework, for use by -fself-test.
2 1.1.1.1.4.2 martin Copyright (C) 2015-2017 Free Software Foundation, Inc.
3 1.1.1.1.4.2 martin
4 1.1.1.1.4.2 martin This file is part of GCC.
5 1.1.1.1.4.2 martin
6 1.1.1.1.4.2 martin GCC is free software; you can redistribute it and/or modify it under
7 1.1.1.1.4.2 martin the terms of the GNU General Public License as published by the Free
8 1.1.1.1.4.2 martin Software Foundation; either version 3, or (at your option) any later
9 1.1.1.1.4.2 martin version.
10 1.1.1.1.4.2 martin
11 1.1.1.1.4.2 martin GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 1.1.1.1.4.2 martin WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 1.1.1.1.4.2 martin FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 1.1.1.1.4.2 martin for more details.
15 1.1.1.1.4.2 martin
16 1.1.1.1.4.2 martin You should have received a copy of the GNU General Public License
17 1.1.1.1.4.2 martin along with GCC; see the file COPYING3. If not see
18 1.1.1.1.4.2 martin <http://www.gnu.org/licenses/>. */
19 1.1.1.1.4.2 martin
20 1.1.1.1.4.2 martin #ifndef GCC_SELFTEST_H
21 1.1.1.1.4.2 martin #define GCC_SELFTEST_H
22 1.1.1.1.4.2 martin
23 1.1.1.1.4.2 martin /* The selftest code should entirely disappear in a production
24 1.1.1.1.4.2 martin configuration, hence we guard all of it with #if CHECKING_P. */
25 1.1.1.1.4.2 martin
26 1.1.1.1.4.2 martin #if CHECKING_P
27 1.1.1.1.4.2 martin
28 1.1.1.1.4.2 martin namespace selftest {
29 1.1.1.1.4.2 martin
30 1.1.1.1.4.2 martin /* A struct describing the source-location of a selftest, to make it
31 1.1.1.1.4.2 martin easier to track down failing tests. */
32 1.1.1.1.4.2 martin
33 1.1.1.1.4.2 martin struct location
34 1.1.1.1.4.2 martin {
35 1.1.1.1.4.2 martin location (const char *file, int line, const char *function)
36 1.1.1.1.4.2 martin : m_file (file), m_line (line), m_function (function) {}
37 1.1.1.1.4.2 martin
38 1.1.1.1.4.2 martin const char *m_file;
39 1.1.1.1.4.2 martin int m_line;
40 1.1.1.1.4.2 martin const char *m_function;
41 1.1.1.1.4.2 martin };
42 1.1.1.1.4.2 martin
43 1.1.1.1.4.2 martin /* A macro for use in selftests and by the ASSERT_ macros below,
44 1.1.1.1.4.2 martin constructing a selftest::location for the current source location. */
45 1.1.1.1.4.2 martin
46 1.1.1.1.4.2 martin #define SELFTEST_LOCATION \
47 1.1.1.1.4.2 martin (::selftest::location (__FILE__, __LINE__, __FUNCTION__))
48 1.1.1.1.4.2 martin
49 1.1.1.1.4.2 martin /* The entrypoint for running all tests. */
50 1.1.1.1.4.2 martin
51 1.1.1.1.4.2 martin extern void run_tests ();
52 1.1.1.1.4.2 martin
53 1.1.1.1.4.2 martin /* Record the successful outcome of some aspect of the test. */
54 1.1.1.1.4.2 martin
55 1.1.1.1.4.2 martin extern void pass (const location &loc, const char *msg);
56 1.1.1.1.4.2 martin
57 1.1.1.1.4.2 martin /* Report the failed outcome of some aspect of the test and abort. */
58 1.1.1.1.4.2 martin
59 1.1.1.1.4.2 martin extern void fail (const location &loc, const char *msg)
60 1.1.1.1.4.2 martin ATTRIBUTE_NORETURN;
61 1.1.1.1.4.2 martin
62 1.1.1.1.4.2 martin /* As "fail", but using printf-style formatted output. */
63 1.1.1.1.4.2 martin
64 1.1.1.1.4.2 martin extern void fail_formatted (const location &loc, const char *fmt, ...)
65 1.1.1.1.4.2 martin ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
66 1.1.1.1.4.2 martin
67 1.1.1.1.4.2 martin /* Implementation detail of ASSERT_STREQ. */
68 1.1.1.1.4.2 martin
69 1.1.1.1.4.2 martin extern void assert_streq (const location &loc,
70 1.1.1.1.4.2 martin const char *desc_expected, const char *desc_actual,
71 1.1.1.1.4.2 martin const char *val_expected, const char *val_actual);
72 1.1.1.1.4.2 martin
73 1.1.1.1.4.2 martin /* Implementation detail of ASSERT_STR_CONTAINS. */
74 1.1.1.1.4.2 martin
75 1.1.1.1.4.2 martin extern void assert_str_contains (const location &loc,
76 1.1.1.1.4.2 martin const char *desc_haystack,
77 1.1.1.1.4.2 martin const char *desc_needle,
78 1.1.1.1.4.2 martin const char *val_haystack,
79 1.1.1.1.4.2 martin const char *val_needle);
80 1.1.1.1.4.2 martin
81 1.1.1.1.4.2 martin /* A named temporary file for use in selftests.
82 1.1.1.1.4.2 martin Usable for writing out files, and as the base class for
83 1.1.1.1.4.2 martin temp_source_file.
84 1.1.1.1.4.2 martin The file is unlinked in the destructor. */
85 1.1.1.1.4.2 martin
86 1.1.1.1.4.2 martin class named_temp_file
87 1.1.1.1.4.2 martin {
88 1.1.1.1.4.2 martin public:
89 1.1.1.1.4.2 martin named_temp_file (const char *suffix);
90 1.1.1.1.4.2 martin ~named_temp_file ();
91 1.1.1.1.4.2 martin const char *get_filename () const { return m_filename; }
92 1.1.1.1.4.2 martin
93 1.1.1.1.4.2 martin private:
94 1.1.1.1.4.2 martin char *m_filename;
95 1.1.1.1.4.2 martin };
96 1.1.1.1.4.2 martin
97 1.1.1.1.4.2 martin /* A class for writing out a temporary sourcefile for use in selftests
98 1.1.1.1.4.2 martin of input handling. */
99 1.1.1.1.4.2 martin
100 1.1.1.1.4.2 martin class temp_source_file : public named_temp_file
101 1.1.1.1.4.2 martin {
102 1.1.1.1.4.2 martin public:
103 1.1.1.1.4.2 martin temp_source_file (const location &loc, const char *suffix,
104 1.1.1.1.4.2 martin const char *content);
105 1.1.1.1.4.2 martin };
106 1.1.1.1.4.2 martin
107 1.1.1.1.4.2 martin /* Various selftests involving location-handling require constructing a
108 1.1.1.1.4.2 martin line table and one or more line maps within it.
109 1.1.1.1.4.2 martin
110 1.1.1.1.4.2 martin For maximum test coverage we want to run these tests with a variety
111 1.1.1.1.4.2 martin of situations:
112 1.1.1.1.4.2 martin - line_table->default_range_bits: some frontends use a non-zero value
113 1.1.1.1.4.2 martin and others use zero
114 1.1.1.1.4.2 martin - the fallback modes within line-map.c: there are various threshold
115 1.1.1.1.4.2 martin values for source_location/location_t beyond line-map.c changes
116 1.1.1.1.4.2 martin behavior (disabling of the range-packing optimization, disabling
117 1.1.1.1.4.2 martin of column-tracking). We can exercise these by starting the line_table
118 1.1.1.1.4.2 martin at interesting values at or near these thresholds.
119 1.1.1.1.4.2 martin
120 1.1.1.1.4.2 martin The following struct describes a particular case within our test
121 1.1.1.1.4.2 martin matrix. */
122 1.1.1.1.4.2 martin
123 1.1.1.1.4.2 martin struct line_table_case;
124 1.1.1.1.4.2 martin
125 1.1.1.1.4.2 martin /* A class for overriding the global "line_table" within a selftest,
126 1.1.1.1.4.2 martin restoring its value afterwards. At most one instance of this
127 1.1.1.1.4.2 martin class can exist at once, due to the need to keep the old value
128 1.1.1.1.4.2 martin of line_table as a GC root. */
129 1.1.1.1.4.2 martin
130 1.1.1.1.4.2 martin class line_table_test
131 1.1.1.1.4.2 martin {
132 1.1.1.1.4.2 martin public:
133 1.1.1.1.4.2 martin /* Default constructor. Override "line_table", using sane defaults
134 1.1.1.1.4.2 martin for the temporary line_table. */
135 1.1.1.1.4.2 martin line_table_test ();
136 1.1.1.1.4.2 martin
137 1.1.1.1.4.2 martin /* Constructor. Override "line_table", using the case described by C. */
138 1.1.1.1.4.2 martin line_table_test (const line_table_case &c);
139 1.1.1.1.4.2 martin
140 1.1.1.1.4.2 martin /* Destructor. Restore the saved line_table. */
141 1.1.1.1.4.2 martin ~line_table_test ();
142 1.1.1.1.4.2 martin };
143 1.1.1.1.4.2 martin
144 1.1.1.1.4.2 martin /* Run TESTCASE multiple times, once for each case in our test matrix. */
145 1.1.1.1.4.2 martin
146 1.1.1.1.4.2 martin extern void
147 1.1.1.1.4.2 martin for_each_line_table_case (void (*testcase) (const line_table_case &));
148 1.1.1.1.4.2 martin
149 1.1.1.1.4.2 martin /* Read the contents of PATH into memory, returning a 0-terminated buffer
150 1.1.1.1.4.2 martin that must be freed by the caller.
151 1.1.1.1.4.2 martin Fail (and abort) if there are any problems, with LOC as the reported
152 1.1.1.1.4.2 martin location of the failure. */
153 1.1.1.1.4.2 martin
154 1.1.1.1.4.2 martin extern char *read_file (const location &loc, const char *path);
155 1.1.1.1.4.2 martin
156 1.1.1.1.4.2 martin /* A helper function for writing tests that interact with the
157 1.1.1.1.4.2 martin garbage collector. */
158 1.1.1.1.4.2 martin
159 1.1.1.1.4.2 martin extern void forcibly_ggc_collect ();
160 1.1.1.1.4.2 martin
161 1.1.1.1.4.2 martin /* Convert a path relative to SRCDIR/gcc/testsuite/selftests
162 1.1.1.1.4.2 martin to a real path (either absolute, or relative to pwd).
163 1.1.1.1.4.2 martin The result should be freed by the caller. */
164 1.1.1.1.4.2 martin
165 1.1.1.1.4.2 martin extern char *locate_file (const char *path);
166 1.1.1.1.4.2 martin
167 1.1.1.1.4.2 martin /* The path of SRCDIR/testsuite/selftests. */
168 1.1.1.1.4.2 martin
169 1.1.1.1.4.2 martin extern const char *path_to_selftest_files;
170 1.1.1.1.4.2 martin
171 1.1.1.1.4.2 martin /* Declarations for specific families of tests (by source file), in
172 1.1.1.1.4.2 martin alphabetical order. */
173 1.1.1.1.4.2 martin extern void bitmap_c_tests ();
174 1.1.1.1.4.2 martin extern void diagnostic_c_tests ();
175 1.1.1.1.4.2 martin extern void diagnostic_show_locus_c_tests ();
176 1.1.1.1.4.2 martin extern void edit_context_c_tests ();
177 1.1.1.1.4.2 martin extern void et_forest_c_tests ();
178 1.1.1.1.4.2 martin extern void fold_const_c_tests ();
179 1.1.1.1.4.2 martin extern void fibonacci_heap_c_tests ();
180 1.1.1.1.4.2 martin extern void function_tests_c_tests ();
181 1.1.1.1.4.2 martin extern void gimple_c_tests ();
182 1.1.1.1.4.2 martin extern void ggc_tests_c_tests ();
183 1.1.1.1.4.2 martin extern void hash_map_tests_c_tests ();
184 1.1.1.1.4.2 martin extern void hash_set_tests_c_tests ();
185 1.1.1.1.4.2 martin extern void input_c_tests ();
186 1.1.1.1.4.2 martin extern void pretty_print_c_tests ();
187 1.1.1.1.4.2 martin extern void read_rtl_function_c_tests ();
188 1.1.1.1.4.2 martin extern void rtl_tests_c_tests ();
189 1.1.1.1.4.2 martin extern void selftest_c_tests ();
190 1.1.1.1.4.2 martin extern void spellcheck_c_tests ();
191 1.1.1.1.4.2 martin extern void spellcheck_tree_c_tests ();
192 1.1.1.1.4.2 martin extern void sreal_c_tests ();
193 1.1.1.1.4.2 martin extern void store_merging_c_tests ();
194 1.1.1.1.4.2 martin extern void typed_splay_tree_c_tests ();
195 1.1.1.1.4.2 martin extern void tree_c_tests ();
196 1.1.1.1.4.2 martin extern void tree_cfg_c_tests ();
197 1.1.1.1.4.2 martin extern void vec_c_tests ();
198 1.1.1.1.4.2 martin extern void wide_int_cc_tests ();
199 1.1.1.1.4.2 martin
200 1.1.1.1.4.2 martin extern int num_passes;
201 1.1.1.1.4.2 martin
202 1.1.1.1.4.2 martin } /* end of namespace selftest. */
203 1.1.1.1.4.2 martin
204 1.1.1.1.4.2 martin /* Macros for writing tests. */
205 1.1.1.1.4.2 martin
206 1.1.1.1.4.2 martin /* Evaluate EXPR and coerce to bool, calling
207 1.1.1.1.4.2 martin ::selftest::pass if it is true,
208 1.1.1.1.4.2 martin ::selftest::fail if it false. */
209 1.1.1.1.4.2 martin
210 1.1.1.1.4.2 martin #define ASSERT_TRUE(EXPR) \
211 1.1.1.1.4.2 martin ASSERT_TRUE_AT (SELFTEST_LOCATION, (EXPR))
212 1.1.1.1.4.2 martin
213 1.1.1.1.4.2 martin /* Like ASSERT_TRUE, but treat LOC as the effective location of the
214 1.1.1.1.4.2 martin selftest. */
215 1.1.1.1.4.2 martin
216 1.1.1.1.4.2 martin #define ASSERT_TRUE_AT(LOC, EXPR) \
217 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
218 1.1.1.1.4.2 martin const char *desc = "ASSERT_TRUE (" #EXPR ")"; \
219 1.1.1.1.4.2 martin bool actual = (EXPR); \
220 1.1.1.1.4.2 martin if (actual) \
221 1.1.1.1.4.2 martin ::selftest::pass ((LOC), desc); \
222 1.1.1.1.4.2 martin else \
223 1.1.1.1.4.2 martin ::selftest::fail ((LOC), desc); \
224 1.1.1.1.4.2 martin SELFTEST_END_STMT
225 1.1.1.1.4.2 martin
226 1.1.1.1.4.2 martin /* Evaluate EXPR and coerce to bool, calling
227 1.1.1.1.4.2 martin ::selftest::pass if it is false,
228 1.1.1.1.4.2 martin ::selftest::fail if it true. */
229 1.1.1.1.4.2 martin
230 1.1.1.1.4.2 martin #define ASSERT_FALSE(EXPR) \
231 1.1.1.1.4.2 martin ASSERT_FALSE_AT (SELFTEST_LOCATION, (EXPR))
232 1.1.1.1.4.2 martin
233 1.1.1.1.4.2 martin /* Like ASSERT_FALSE, but treat LOC as the effective location of the
234 1.1.1.1.4.2 martin selftest. */
235 1.1.1.1.4.2 martin
236 1.1.1.1.4.2 martin #define ASSERT_FALSE_AT(LOC, EXPR) \
237 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
238 1.1.1.1.4.2 martin const char *desc = "ASSERT_FALSE (" #EXPR ")"; \
239 1.1.1.1.4.2 martin bool actual = (EXPR); \
240 1.1.1.1.4.2 martin if (actual) \
241 1.1.1.1.4.2 martin ::selftest::fail ((LOC), desc); \
242 1.1.1.1.4.2 martin else \
243 1.1.1.1.4.2 martin ::selftest::pass ((LOC), desc); \
244 1.1.1.1.4.2 martin SELFTEST_END_STMT
245 1.1.1.1.4.2 martin
246 1.1.1.1.4.2 martin /* Evaluate EXPECTED and ACTUAL and compare them with ==, calling
247 1.1.1.1.4.2 martin ::selftest::pass if they are equal,
248 1.1.1.1.4.2 martin ::selftest::fail if they are non-equal. */
249 1.1.1.1.4.2 martin
250 1.1.1.1.4.2 martin #define ASSERT_EQ(EXPECTED, ACTUAL) \
251 1.1.1.1.4.2 martin ASSERT_EQ_AT ((SELFTEST_LOCATION), (EXPECTED), (ACTUAL))
252 1.1.1.1.4.2 martin
253 1.1.1.1.4.2 martin /* Like ASSERT_EQ, but treat LOC as the effective location of the
254 1.1.1.1.4.2 martin selftest. */
255 1.1.1.1.4.2 martin
256 1.1.1.1.4.2 martin #define ASSERT_EQ_AT(LOC, EXPECTED, ACTUAL) \
257 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
258 1.1.1.1.4.2 martin const char *desc = "ASSERT_EQ (" #EXPECTED ", " #ACTUAL ")"; \
259 1.1.1.1.4.2 martin if ((EXPECTED) == (ACTUAL)) \
260 1.1.1.1.4.2 martin ::selftest::pass ((LOC), desc); \
261 1.1.1.1.4.2 martin else \
262 1.1.1.1.4.2 martin ::selftest::fail ((LOC), desc); \
263 1.1.1.1.4.2 martin SELFTEST_END_STMT
264 1.1.1.1.4.2 martin
265 1.1.1.1.4.2 martin /* Evaluate EXPECTED and ACTUAL and compare them with !=, calling
266 1.1.1.1.4.2 martin ::selftest::pass if they are non-equal,
267 1.1.1.1.4.2 martin ::selftest::fail if they are equal. */
268 1.1.1.1.4.2 martin
269 1.1.1.1.4.2 martin #define ASSERT_NE(EXPECTED, ACTUAL) \
270 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
271 1.1.1.1.4.2 martin const char *desc = "ASSERT_NE (" #EXPECTED ", " #ACTUAL ")"; \
272 1.1.1.1.4.2 martin if ((EXPECTED) != (ACTUAL)) \
273 1.1.1.1.4.2 martin ::selftest::pass (SELFTEST_LOCATION, desc); \
274 1.1.1.1.4.2 martin else \
275 1.1.1.1.4.2 martin ::selftest::fail (SELFTEST_LOCATION, desc); \
276 1.1.1.1.4.2 martin SELFTEST_END_STMT
277 1.1.1.1.4.2 martin
278 1.1.1.1.4.2 martin /* Evaluate EXPECTED and ACTUAL and compare them with strcmp, calling
279 1.1.1.1.4.2 martin ::selftest::pass if they are equal,
280 1.1.1.1.4.2 martin ::selftest::fail if they are non-equal. */
281 1.1.1.1.4.2 martin
282 1.1.1.1.4.2 martin #define ASSERT_STREQ(EXPECTED, ACTUAL) \
283 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
284 1.1.1.1.4.2 martin ::selftest::assert_streq (SELFTEST_LOCATION, #EXPECTED, #ACTUAL, \
285 1.1.1.1.4.2 martin (EXPECTED), (ACTUAL)); \
286 1.1.1.1.4.2 martin SELFTEST_END_STMT
287 1.1.1.1.4.2 martin
288 1.1.1.1.4.2 martin /* Like ASSERT_STREQ, but treat LOC as the effective location of the
289 1.1.1.1.4.2 martin selftest. */
290 1.1.1.1.4.2 martin
291 1.1.1.1.4.2 martin #define ASSERT_STREQ_AT(LOC, EXPECTED, ACTUAL) \
292 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
293 1.1.1.1.4.2 martin ::selftest::assert_streq ((LOC), #EXPECTED, #ACTUAL, \
294 1.1.1.1.4.2 martin (EXPECTED), (ACTUAL)); \
295 1.1.1.1.4.2 martin SELFTEST_END_STMT
296 1.1.1.1.4.2 martin
297 1.1.1.1.4.2 martin /* Evaluate HAYSTACK and NEEDLE and use strstr to determine if NEEDLE
298 1.1.1.1.4.2 martin is within HAYSTACK.
299 1.1.1.1.4.2 martin ::selftest::pass if NEEDLE is found.
300 1.1.1.1.4.2 martin ::selftest::fail if it is not found. */
301 1.1.1.1.4.2 martin
302 1.1.1.1.4.2 martin #define ASSERT_STR_CONTAINS(HAYSTACK, NEEDLE) \
303 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
304 1.1.1.1.4.2 martin ::selftest::assert_str_contains (SELFTEST_LOCATION, #HAYSTACK, #NEEDLE, \
305 1.1.1.1.4.2 martin (HAYSTACK), (NEEDLE)); \
306 1.1.1.1.4.2 martin SELFTEST_END_STMT
307 1.1.1.1.4.2 martin
308 1.1.1.1.4.2 martin /* Evaluate PRED1 (VAL1), calling ::selftest::pass if it is true,
309 1.1.1.1.4.2 martin ::selftest::fail if it is false. */
310 1.1.1.1.4.2 martin
311 1.1.1.1.4.2 martin #define ASSERT_PRED1(PRED1, VAL1) \
312 1.1.1.1.4.2 martin SELFTEST_BEGIN_STMT \
313 1.1.1.1.4.2 martin const char *desc = "ASSERT_PRED1 (" #PRED1 ", " #VAL1 ")"; \
314 1.1.1.1.4.2 martin bool actual = (PRED1) (VAL1); \
315 1.1.1.1.4.2 martin if (actual) \
316 1.1.1.1.4.2 martin ::selftest::pass (SELFTEST_LOCATION, desc); \
317 1.1.1.1.4.2 martin else \
318 1.1.1.1.4.2 martin ::selftest::fail (SELFTEST_LOCATION, desc); \
319 1.1.1.1.4.2 martin SELFTEST_END_STMT
320 1.1.1.1.4.2 martin
321 1.1.1.1.4.2 martin #define SELFTEST_BEGIN_STMT do {
322 1.1.1.1.4.2 martin #define SELFTEST_END_STMT } while (0)
323 1.1.1.1.4.2 martin
324 1.1.1.1.4.2 martin #endif /* #if CHECKING_P */
325 1.1.1.1.4.2 martin
326 1.1.1.1.4.2 martin #endif /* GCC_SELFTEST_H */
327