Line data Source code
1 : /* A self-testing framework, for use by -fself-test.
2 : Copyright (C) 2015-2023 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #ifndef GCC_SELFTEST_H
21 : #define GCC_SELFTEST_H
22 :
23 : /* The selftest code should entirely disappear in a production
24 : configuration, hence we guard all of it with #if CHECKING_P. */
25 :
26 : #if CHECKING_P
27 :
28 : namespace selftest {
29 :
30 : /* A struct describing the source-location of a selftest, to make it
31 : easier to track down failing tests. */
32 :
33 : class location
34 : {
35 : public:
36 30 : location (const char *file, int line, const char *function)
37 30 : : m_file (file), m_line (line), m_function (function) {}
38 :
39 : const char *m_file;
40 : int m_line;
41 : const char *m_function;
42 : };
43 :
44 : /* A macro for use in selftests and by the ASSERT_ macros below,
45 : constructing a selftest::location for the current source location. */
46 :
47 : #define SELFTEST_LOCATION \
48 : (::selftest::location (__FILE__, __LINE__, __FUNCTION__))
49 :
50 : /* The entrypoint for running all tests. */
51 :
52 : extern void run_tests ();
53 :
54 : /* Record the successful outcome of some aspect of the test. */
55 :
56 : extern void pass (const location &loc, const char *msg);
57 :
58 : /* Report the failed outcome of some aspect of the test and abort. */
59 :
60 : extern void fail (const location &loc, const char *msg)
61 : ATTRIBUTE_NORETURN;
62 :
63 : /* As "fail", but using printf-style formatted output. */
64 :
65 : extern void fail_formatted (const location &loc, const char *fmt, ...)
66 : ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
67 :
68 : /* Implementation detail of ASSERT_STREQ. */
69 :
70 : extern void assert_streq (const location &loc,
71 : const char *desc_val1, const char *desc_val2,
72 : const char *val1, const char *val2);
73 :
74 : /* Implementation detail of ASSERT_STR_CONTAINS. */
75 :
76 : extern void assert_str_contains (const location &loc,
77 : const char *desc_haystack,
78 : const char *desc_needle,
79 : const char *val_haystack,
80 : const char *val_needle);
81 :
82 : /* Implementation detail of ASSERT_STR_STARTSWITH. */
83 :
84 : extern void assert_str_startswith (const location &loc,
85 : const char *desc_str,
86 : const char *desc_prefix,
87 : const char *val_str,
88 : const char *val_prefix);
89 :
90 :
91 : /* A named temporary file for use in selftests.
92 : Usable for writing out files, and as the base class for
93 : temp_source_file.
94 : The file is unlinked in the destructor. */
95 :
96 : class named_temp_file
97 : {
98 : public:
99 : named_temp_file (const char *suffix);
100 : ~named_temp_file ();
101 : const char *get_filename () const { return m_filename; }
102 :
103 : private:
104 : char *m_filename;
105 : };
106 :
107 : /* A class for writing out a temporary sourcefile for use in selftests
108 : of input handling. */
109 :
110 : class temp_source_file : public named_temp_file
111 : {
112 : public:
113 : temp_source_file (const location &loc, const char *suffix,
114 : const char *content);
115 : temp_source_file (const location &loc, const char *suffix,
116 : const char *content, size_t sz);
117 : };
118 :
119 : /* RAII-style class for avoiding introducing locale-specific differences
120 : in strings containing localized quote marks, by temporarily overriding
121 : the "open_quote" and "close_quote" globals to something hardcoded.
122 :
123 : Specifically, the C locale's values are used:
124 : - open_quote becomes "`"
125 : - close_quote becomes "'"
126 : for the lifetime of the object. */
127 :
128 : class auto_fix_quotes
129 : {
130 : public:
131 : auto_fix_quotes ();
132 : ~auto_fix_quotes ();
133 :
134 : private:
135 : const char *m_saved_open_quote;
136 : const char *m_saved_close_quote;
137 : };
138 :
139 : /* Various selftests involving location-handling require constructing a
140 : line table and one or more line maps within it.
141 :
142 : For maximum test coverage we want to run these tests with a variety
143 : of situations:
144 : - line_table->default_range_bits: some frontends use a non-zero value
145 : and others use zero
146 : - the fallback modes within line-map.cc: there are various threshold
147 : values for location_t beyond line-map.cc changes
148 : behavior (disabling of the range-packing optimization, disabling
149 : of column-tracking). We can exercise these by starting the line_table
150 : at interesting values at or near these thresholds.
151 :
152 : The following struct describes a particular case within our test
153 : matrix. */
154 :
155 : class line_table_case;
156 :
157 : /* A class for overriding the global "line_table" within a selftest,
158 : restoring its value afterwards. At most one instance of this
159 : class can exist at once, due to the need to keep the old value
160 : of line_table as a GC root. */
161 :
162 : class line_table_test
163 : {
164 : public:
165 : /* Default constructor. Override "line_table", using sane defaults
166 : for the temporary line_table. */
167 : line_table_test ();
168 :
169 : /* Constructor. Override "line_table", using the case described by C. */
170 : line_table_test (const line_table_case &c);
171 :
172 : /* Destructor. Restore the saved line_table. */
173 : ~line_table_test ();
174 : };
175 :
176 : /* Helper function for selftests that need a function decl. */
177 :
178 : extern tree make_fndecl (tree return_type,
179 : const char *name,
180 : vec <tree> ¶m_types,
181 : bool is_variadic = false);
182 :
183 : /* Run TESTCASE multiple times, once for each case in our test matrix. */
184 :
185 : extern void
186 : for_each_line_table_case (void (*testcase) (const line_table_case &));
187 :
188 : /* Read the contents of PATH into memory, returning a 0-terminated buffer
189 : that must be freed by the caller.
190 : Fail (and abort) if there are any problems, with LOC as the reported
191 : location of the failure. */
192 :
193 : extern char *read_file (const location &loc, const char *path);
194 :
195 : /* Convert a path relative to SRCDIR/gcc/testsuite/selftests
196 : to a real path (either absolute, or relative to pwd).
197 : The result should be freed by the caller. */
198 :
199 : extern char *locate_file (const char *path);
200 :
201 : /* The path of SRCDIR/testsuite/selftests. */
202 :
203 : extern const char *path_to_selftest_files;
204 :
205 : /* selftest::test_runner is an implementation detail of selftest::run_tests,
206 : exposed here to allow plugins to run their own suites of tests. */
207 :
208 : class test_runner
209 : {
210 : public:
211 : test_runner (const char *name);
212 : ~test_runner ();
213 :
214 : private:
215 : const char *m_name;
216 : long m_start_time;
217 : };
218 :
219 : /* Declarations for specific families of tests (by source file), in
220 : alphabetical order. */
221 : extern void attribs_cc_tests ();
222 : extern void bitmap_cc_tests ();
223 : extern void cgraph_cc_tests ();
224 : extern void convert_cc_tests ();
225 : extern void diagnostic_format_json_cc_tests ();
226 : extern void diagnostic_show_locus_cc_tests ();
227 : extern void digraph_cc_tests ();
228 : extern void dumpfile_cc_tests ();
229 : extern void edit_context_cc_tests ();
230 : extern void et_forest_cc_tests ();
231 : extern void fibonacci_heap_cc_tests ();
232 : extern void fold_const_cc_tests ();
233 : extern void function_tests_cc_tests ();
234 : extern void ggc_tests_cc_tests ();
235 : extern void gimple_cc_tests ();
236 : extern void hash_map_tests_cc_tests ();
237 : extern void hash_set_tests_cc_tests ();
238 : extern void input_cc_tests ();
239 : extern void json_cc_tests ();
240 : extern void optinfo_emit_json_cc_tests ();
241 : extern void opts_cc_tests ();
242 : extern void ordered_hash_map_tests_cc_tests ();
243 : extern void predict_cc_tests ();
244 : extern void pretty_print_cc_tests ();
245 : extern void range_tests ();
246 : extern void range_op_tests ();
247 : extern void relation_tests ();
248 : extern void gimple_range_tests ();
249 : extern void read_rtl_function_cc_tests ();
250 : extern void rtl_tests_cc_tests ();
251 : extern void sbitmap_cc_tests ();
252 : extern void selftest_cc_tests ();
253 : extern void simplify_rtx_cc_tests ();
254 : extern void spellcheck_cc_tests ();
255 : extern void spellcheck_tree_cc_tests ();
256 : extern void splay_tree_cc_tests ();
257 : extern void sreal_cc_tests ();
258 : extern void store_merging_cc_tests ();
259 : extern void tree_cc_tests ();
260 : extern void tree_cfg_cc_tests ();
261 : extern void tree_diagnostic_path_cc_tests ();
262 : extern void tristate_cc_tests ();
263 : extern void typed_splay_tree_cc_tests ();
264 : extern void vec_cc_tests ();
265 : extern void vec_perm_indices_cc_tests ();
266 : extern void wide_int_cc_tests ();
267 : extern void opt_suggestions_cc_tests ();
268 : extern void dbgcnt_cc_tests ();
269 : extern void ipa_modref_tree_cc_tests ();
270 :
271 : extern int num_passes;
272 :
273 : } /* end of namespace selftest. */
274 :
275 : /* Macros for writing tests. */
276 :
277 : /* Evaluate EXPR and coerce to bool, calling
278 : ::selftest::pass if it is true,
279 : ::selftest::fail if it false. */
280 :
281 : #define ASSERT_TRUE(EXPR) \
282 : ASSERT_TRUE_AT (SELFTEST_LOCATION, (EXPR))
283 :
284 : /* Like ASSERT_TRUE, but treat LOC as the effective location of the
285 : selftest. */
286 :
287 : #define ASSERT_TRUE_AT(LOC, EXPR) \
288 : SELFTEST_BEGIN_STMT \
289 : const char *desc_ = "ASSERT_TRUE (" #EXPR ")"; \
290 : bool actual_ = (EXPR); \
291 : if (actual_) \
292 : ::selftest::pass ((LOC), desc_); \
293 : else \
294 : ::selftest::fail ((LOC), desc_); \
295 : SELFTEST_END_STMT
296 :
297 : /* Evaluate EXPR and coerce to bool, calling
298 : ::selftest::pass if it is false,
299 : ::selftest::fail if it true. */
300 :
301 : #define ASSERT_FALSE(EXPR) \
302 : ASSERT_FALSE_AT (SELFTEST_LOCATION, (EXPR))
303 :
304 : /* Like ASSERT_FALSE, but treat LOC as the effective location of the
305 : selftest. */
306 :
307 : #define ASSERT_FALSE_AT(LOC, EXPR) \
308 : SELFTEST_BEGIN_STMT \
309 : const char *desc_ = "ASSERT_FALSE (" #EXPR ")"; \
310 : bool actual_ = (EXPR); \
311 : if (actual_) \
312 : ::selftest::fail ((LOC), desc_); \
313 : else \
314 : ::selftest::pass ((LOC), desc_); \
315 : SELFTEST_END_STMT
316 :
317 : /* Evaluate VAL1 and VAL2 and compare them with ==, calling
318 : ::selftest::pass if they are equal,
319 : ::selftest::fail if they are non-equal. */
320 :
321 : #define ASSERT_EQ(VAL1, VAL2) \
322 : ASSERT_EQ_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
323 :
324 : /* Like ASSERT_EQ, but treat LOC as the effective location of the
325 : selftest. */
326 :
327 : #define ASSERT_EQ_AT(LOC, VAL1, VAL2) \
328 : SELFTEST_BEGIN_STMT \
329 : const char *desc_ = "ASSERT_EQ (" #VAL1 ", " #VAL2 ")"; \
330 : if ((VAL1) == (VAL2)) \
331 : ::selftest::pass ((LOC), desc_); \
332 : else \
333 : ::selftest::fail ((LOC), desc_); \
334 : SELFTEST_END_STMT
335 :
336 : /* Evaluate VAL1 and VAL2 and compare them with known_eq, calling
337 : ::selftest::pass if they are always equal,
338 : ::selftest::fail if they might be non-equal. */
339 :
340 : #define ASSERT_KNOWN_EQ(VAL1, VAL2) \
341 : ASSERT_KNOWN_EQ_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
342 :
343 : /* Like ASSERT_KNOWN_EQ, but treat LOC as the effective location of the
344 : selftest. */
345 :
346 : #define ASSERT_KNOWN_EQ_AT(LOC, VAL1, VAL2) \
347 : SELFTEST_BEGIN_STMT \
348 : const char *desc = "ASSERT_KNOWN_EQ (" #VAL1 ", " #VAL2 ")"; \
349 : if (known_eq (VAL1, VAL2)) \
350 : ::selftest::pass ((LOC), desc); \
351 : else \
352 : ::selftest::fail ((LOC), desc); \
353 : SELFTEST_END_STMT
354 :
355 : /* Evaluate VAL1 and VAL2 and compare them with !=, calling
356 : ::selftest::pass if they are non-equal,
357 : ::selftest::fail if they are equal. */
358 :
359 : #define ASSERT_NE(VAL1, VAL2) \
360 : SELFTEST_BEGIN_STMT \
361 : const char *desc_ = "ASSERT_NE (" #VAL1 ", " #VAL2 ")"; \
362 : if ((VAL1) != (VAL2)) \
363 : ::selftest::pass (SELFTEST_LOCATION, desc_); \
364 : else \
365 : ::selftest::fail (SELFTEST_LOCATION, desc_); \
366 : SELFTEST_END_STMT
367 :
368 : /* Evaluate VAL1 and VAL2 and compare them with maybe_ne, calling
369 : ::selftest::pass if they might be non-equal,
370 : ::selftest::fail if they are known to be equal. */
371 :
372 : #define ASSERT_MAYBE_NE(VAL1, VAL2) \
373 : ASSERT_MAYBE_NE_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
374 :
375 : /* Like ASSERT_MAYBE_NE, but treat LOC as the effective location of the
376 : selftest. */
377 :
378 : #define ASSERT_MAYBE_NE_AT(LOC, VAL1, VAL2) \
379 : SELFTEST_BEGIN_STMT \
380 : const char *desc = "ASSERT_MAYBE_NE (" #VAL1 ", " #VAL2 ")"; \
381 : if (maybe_ne (VAL1, VAL2)) \
382 : ::selftest::pass ((LOC), desc); \
383 : else \
384 : ::selftest::fail ((LOC), desc); \
385 : SELFTEST_END_STMT
386 :
387 : /* Evaluate LHS and RHS and compare them with >, calling
388 : ::selftest::pass if LHS > RHS,
389 : ::selftest::fail otherwise. */
390 :
391 : #define ASSERT_GT(LHS, RHS) \
392 : ASSERT_GT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
393 :
394 : /* Like ASSERT_GT, but treat LOC as the effective location of the
395 : selftest. */
396 :
397 : #define ASSERT_GT_AT(LOC, LHS, RHS) \
398 : SELFTEST_BEGIN_STMT \
399 : const char *desc_ = "ASSERT_GT (" #LHS ", " #RHS ")"; \
400 : if ((LHS) > (RHS)) \
401 : ::selftest::pass ((LOC), desc_); \
402 : else \
403 : ::selftest::fail ((LOC), desc_); \
404 : SELFTEST_END_STMT
405 :
406 : /* Evaluate LHS and RHS and compare them with <, calling
407 : ::selftest::pass if LHS < RHS,
408 : ::selftest::fail otherwise. */
409 :
410 : #define ASSERT_LT(LHS, RHS) \
411 : ASSERT_LT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
412 :
413 : /* Like ASSERT_LT, but treat LOC as the effective location of the
414 : selftest. */
415 :
416 : #define ASSERT_LT_AT(LOC, LHS, RHS) \
417 : SELFTEST_BEGIN_STMT \
418 : const char *desc_ = "ASSERT_LT (" #LHS ", " #RHS ")"; \
419 : if ((LHS) < (RHS)) \
420 : ::selftest::pass ((LOC), desc_); \
421 : else \
422 : ::selftest::fail ((LOC), desc_); \
423 : SELFTEST_END_STMT
424 :
425 : /* Evaluate VAL1 and VAL2 and compare them with strcmp, calling
426 : ::selftest::pass if they are equal (and both are non-NULL),
427 : ::selftest::fail if they are non-equal, or are both NULL. */
428 :
429 : #define ASSERT_STREQ(VAL1, VAL2) \
430 : SELFTEST_BEGIN_STMT \
431 : ::selftest::assert_streq (SELFTEST_LOCATION, #VAL1, #VAL2, \
432 : (VAL1), (VAL2)); \
433 : SELFTEST_END_STMT
434 :
435 : /* Like ASSERT_STREQ, but treat LOC as the effective location of the
436 : selftest. */
437 :
438 : #define ASSERT_STREQ_AT(LOC, VAL1, VAL2) \
439 : SELFTEST_BEGIN_STMT \
440 : ::selftest::assert_streq ((LOC), #VAL1, #VAL2, \
441 : (VAL1), (VAL2)); \
442 : SELFTEST_END_STMT
443 :
444 : /* Evaluate HAYSTACK and NEEDLE and use strstr to determine if NEEDLE
445 : is within HAYSTACK.
446 : ::selftest::pass if NEEDLE is found.
447 : ::selftest::fail if it is not found. */
448 :
449 : #define ASSERT_STR_CONTAINS(HAYSTACK, NEEDLE) \
450 : SELFTEST_BEGIN_STMT \
451 : ::selftest::assert_str_contains (SELFTEST_LOCATION, #HAYSTACK, #NEEDLE, \
452 : (HAYSTACK), (NEEDLE)); \
453 : SELFTEST_END_STMT
454 :
455 : /* Like ASSERT_STR_CONTAINS, but treat LOC as the effective location of the
456 : selftest. */
457 :
458 : #define ASSERT_STR_CONTAINS_AT(LOC, HAYSTACK, NEEDLE) \
459 : SELFTEST_BEGIN_STMT \
460 : ::selftest::assert_str_contains (LOC, #HAYSTACK, #NEEDLE, \
461 : (HAYSTACK), (NEEDLE)); \
462 : SELFTEST_END_STMT
463 :
464 : /* Evaluate STR and PREFIX and determine if STR starts with PREFIX.
465 : ::selftest::pass if STR does start with PREFIX.
466 : ::selftest::fail if does not, or either is NULL. */
467 :
468 : #define ASSERT_STR_STARTSWITH(STR, PREFIX) \
469 : SELFTEST_BEGIN_STMT \
470 : ::selftest::assert_str_startswith (SELFTEST_LOCATION, #STR, #PREFIX, \
471 : (STR), (PREFIX)); \
472 : SELFTEST_END_STMT
473 :
474 : /* Evaluate PRED1 (VAL1), calling ::selftest::pass if it is true,
475 : ::selftest::fail if it is false. */
476 :
477 : #define ASSERT_PRED1(PRED1, VAL1) \
478 : SELFTEST_BEGIN_STMT \
479 : const char *desc_ = "ASSERT_PRED1 (" #PRED1 ", " #VAL1 ")"; \
480 : bool actual_ = (PRED1) (VAL1); \
481 : if (actual_) \
482 : ::selftest::pass (SELFTEST_LOCATION, desc_); \
483 : else \
484 : ::selftest::fail (SELFTEST_LOCATION, desc_); \
485 : SELFTEST_END_STMT
486 :
487 : #define SELFTEST_BEGIN_STMT do {
488 : #define SELFTEST_END_STMT } while (0)
489 :
490 : #endif /* #if CHECKING_P */
491 :
492 : #endif /* GCC_SELFTEST_H */
|