1 /* A self-testing framework, for use by -fself-test.
2 Copyright (C) 2015-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
20 #ifndef GCC_SELFTEST_H
21 #define GCC_SELFTEST_H
23 /* The selftest code should entirely disappear in a production
24 configuration, hence we guard all of it with #if CHECKING_P. */
32 /* A struct describing the source-location of a selftest, to make it
33 easier to track down failing tests. */
38 location (const char *file
, int line
, const char *function
)
39 : m_file (file
), m_line (line
), m_function (function
) {}
43 const char *m_function
;
46 /* A macro for use in selftests and by the ASSERT_ macros below,
47 constructing a selftest::location for the current source location. */
49 #define SELFTEST_LOCATION \
50 (::selftest::location (__FILE__, __LINE__, __FUNCTION__))
52 /* The entrypoint for running all tests. */
54 extern void run_tests ();
56 /* Record the successful outcome of some aspect of the test. */
58 extern void pass (const location
&loc
, const char *msg
);
60 /* Report the failed outcome of some aspect of the test and abort. */
62 extern void fail (const location
&loc
, const char *msg
)
65 /* As "fail", but using printf-style formatted output. */
67 extern void fail_formatted (const location
&loc
, const char *fmt
, ...)
68 ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN
;
70 /* Implementation detail of ASSERT_STREQ. */
72 extern void assert_streq (const location
&loc
,
73 const char *desc_val1
, const char *desc_val2
,
74 const char *val1
, const char *val2
);
76 /* Implementation detail of ASSERT_STR_CONTAINS. */
78 extern void assert_str_contains (const location
&loc
,
79 const char *desc_haystack
,
80 const char *desc_needle
,
81 const char *val_haystack
,
82 const char *val_needle
);
84 /* Implementation detail of ASSERT_STR_STARTSWITH. */
86 extern void assert_str_startswith (const location
&loc
,
88 const char *desc_prefix
,
90 const char *val_prefix
);
93 /* A named temporary file for use in selftests.
94 Usable for writing out files, and as the base class for
96 The file is unlinked in the destructor.
97 If the file_cache is non-null, the filename is evicted from
98 the file_cache when the named_temp_file is destroyed. */
100 class named_temp_file
103 named_temp_file (const char *suffix
, file_cache
*fc
= nullptr);
105 const char *get_filename () const { return m_filename
; }
109 file_cache
*m_file_cache
;
112 /* A class for writing out a temporary sourcefile for use in selftests
113 of input handling. */
115 class temp_source_file
: public named_temp_file
118 temp_source_file (const location
&loc
, const char *suffix
,
119 const char *content
, file_cache
*fc
= nullptr);
120 temp_source_file (const location
&loc
, const char *suffix
,
121 const char *content
, size_t sz
);
124 /* RAII-style class for avoiding introducing locale-specific differences
125 in strings containing localized quote marks, by temporarily overriding
126 the "open_quote" and "close_quote" globals to something hardcoded.
128 Specifically, the C locale's values are used:
129 - open_quote becomes "`"
130 - close_quote becomes "'"
131 for the lifetime of the object. */
133 class auto_fix_quotes
140 const char *m_saved_open_quote
;
141 const char *m_saved_close_quote
;
144 /* Various selftests involving location-handling require constructing a
145 line table and one or more line maps within it.
147 For maximum test coverage we want to run these tests with a variety
149 - line_table->default_range_bits: some frontends use a non-zero value
151 - the fallback modes within line-map.cc: there are various threshold
152 values for location_t beyond line-map.cc changes
153 behavior (disabling of the range-packing optimization, disabling
154 of column-tracking). We can exercise these by starting the line_table
155 at interesting values at or near these thresholds.
157 The following struct describes a particular case within our test
160 class line_table_case
;
162 /* A class for overriding the global "line_table" within a selftest,
163 restoring its value afterwards. At most one instance of this
164 class can exist at once, due to the need to keep the old value
165 of line_table as a GC root. */
167 class line_table_test
170 /* Default constructor. Override "line_table", using sane defaults
171 for the temporary line_table. */
174 /* Constructor. Override "line_table", using the case described by C. */
175 line_table_test (const line_table_case
&c
);
177 /* Destructor. Restore the saved line_table. */
181 /* Run TESTCASE multiple times, once for each case in our test matrix. */
184 for_each_line_table_case (void (*testcase
) (const line_table_case
&));
186 /* Read the contents of PATH into memory, returning a 0-terminated buffer
187 that must be freed by the caller.
188 Fail (and abort) if there are any problems, with LOC as the reported
189 location of the failure. */
191 extern char *read_file (const location
&loc
, const char *path
);
193 /* Convert a path relative to SRCDIR/gcc/testsuite/selftests
194 to a real path (either absolute, or relative to pwd).
195 The result should be freed by the caller. */
197 extern char *locate_file (const char *path
);
199 /* The path of SRCDIR/testsuite/selftests. */
201 extern const char *path_to_selftest_files
;
203 /* selftest::test_runner is an implementation detail of selftest::run_tests,
204 exposed here to allow plugins to run their own suites of tests. */
209 test_runner (const char *name
);
217 /* Declarations for specific families of tests (by source file), in
218 alphabetical order. */
219 extern void attribs_cc_tests ();
220 extern void bitmap_cc_tests ();
221 extern void cgraph_cc_tests ();
222 extern void convert_cc_tests ();
223 extern void diagnostic_color_cc_tests ();
224 extern void diagnostic_format_json_cc_tests ();
225 extern void diagnostic_format_sarif_cc_tests ();
226 extern void diagnostic_path_cc_tests ();
227 extern void diagnostic_show_locus_cc_tests ();
228 extern void digraph_cc_tests ();
229 extern void dumpfile_cc_tests ();
230 extern void edit_context_cc_tests ();
231 extern void et_forest_cc_tests ();
232 extern void fibonacci_heap_cc_tests ();
233 extern void fold_const_cc_tests ();
234 extern void function_tests_cc_tests ();
235 extern void gcc_urlifier_cc_tests ();
236 extern void ggc_tests_cc_tests ();
237 extern void gimple_cc_tests ();
238 extern void hash_map_tests_cc_tests ();
239 extern void hash_set_tests_cc_tests ();
240 extern void input_cc_tests ();
241 extern void json_cc_tests ();
242 extern void optinfo_emit_json_cc_tests ();
243 extern void opts_cc_tests ();
244 extern void ordered_hash_map_tests_cc_tests ();
245 extern void predict_cc_tests ();
246 extern void pretty_print_cc_tests ();
247 extern void range_tests ();
248 extern void range_op_tests ();
249 extern void relation_tests ();
250 extern void gimple_range_tests ();
251 extern void read_rtl_function_cc_tests ();
252 extern void rtl_tests_cc_tests ();
253 extern void sbitmap_cc_tests ();
254 extern void selftest_cc_tests ();
255 extern void simple_diagnostic_path_cc_tests ();
256 extern void simplify_rtx_cc_tests ();
257 extern void spellcheck_cc_tests ();
258 extern void spellcheck_tree_cc_tests ();
259 extern void splay_tree_cc_tests ();
260 extern void sreal_cc_tests ();
261 extern void store_merging_cc_tests ();
262 extern void tree_cc_tests ();
263 extern void tree_cfg_cc_tests ();
264 extern void tristate_cc_tests ();
265 extern void typed_splay_tree_cc_tests ();
266 extern void vec_cc_tests ();
267 extern void vec_perm_indices_cc_tests ();
268 extern void wide_int_cc_tests ();
269 extern void opt_suggestions_cc_tests ();
270 extern void dbgcnt_cc_tests ();
271 extern void ipa_modref_tree_cc_tests ();
273 extern int num_passes
;
275 } /* end of namespace selftest. */
277 /* Macros for writing tests. */
279 /* Evaluate EXPR and coerce to bool, calling
280 ::selftest::pass if it is true,
281 ::selftest::fail if it false. */
283 #define ASSERT_TRUE(EXPR) \
284 ASSERT_TRUE_AT (SELFTEST_LOCATION, (EXPR))
286 /* Like ASSERT_TRUE, but treat LOC as the effective location of the
289 #define ASSERT_TRUE_AT(LOC, EXPR) \
290 SELFTEST_BEGIN_STMT \
291 const char *desc_ = "ASSERT_TRUE (" #EXPR ")"; \
292 bool actual_ = (EXPR); \
294 ::selftest::pass ((LOC), desc_); \
296 ::selftest::fail ((LOC), desc_); \
299 /* Evaluate EXPR and coerce to bool, calling
300 ::selftest::pass if it is false,
301 ::selftest::fail if it true. */
303 #define ASSERT_FALSE(EXPR) \
304 ASSERT_FALSE_AT (SELFTEST_LOCATION, (EXPR))
306 /* Like ASSERT_FALSE, but treat LOC as the effective location of the
309 #define ASSERT_FALSE_AT(LOC, EXPR) \
310 SELFTEST_BEGIN_STMT \
311 const char *desc_ = "ASSERT_FALSE (" #EXPR ")"; \
312 bool actual_ = (EXPR); \
314 ::selftest::fail ((LOC), desc_); \
316 ::selftest::pass ((LOC), desc_); \
319 /* Evaluate VAL1 and VAL2 and compare them with ==, calling
320 ::selftest::pass if they are equal,
321 ::selftest::fail if they are non-equal. */
323 #define ASSERT_EQ(VAL1, VAL2) \
324 ASSERT_EQ_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
326 /* Like ASSERT_EQ, but treat LOC as the effective location of the
329 #define ASSERT_EQ_AT(LOC, VAL1, VAL2) \
330 SELFTEST_BEGIN_STMT \
331 const char *desc_ = "ASSERT_EQ (" #VAL1 ", " #VAL2 ")"; \
332 if ((VAL1) == (VAL2)) \
333 ::selftest::pass ((LOC), desc_); \
335 ::selftest::fail ((LOC), desc_); \
338 /* Evaluate VAL1 and VAL2 and compare them with known_eq, calling
339 ::selftest::pass if they are always equal,
340 ::selftest::fail if they might be non-equal. */
342 #define ASSERT_KNOWN_EQ(VAL1, VAL2) \
343 ASSERT_KNOWN_EQ_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
345 /* Like ASSERT_KNOWN_EQ, but treat LOC as the effective location of the
348 #define ASSERT_KNOWN_EQ_AT(LOC, VAL1, VAL2) \
349 SELFTEST_BEGIN_STMT \
350 const char *desc = "ASSERT_KNOWN_EQ (" #VAL1 ", " #VAL2 ")"; \
351 if (known_eq (VAL1, VAL2)) \
352 ::selftest::pass ((LOC), desc); \
354 ::selftest::fail ((LOC), desc); \
357 /* Evaluate VAL1 and VAL2 and compare them with !=, calling
358 ::selftest::pass if they are non-equal,
359 ::selftest::fail if they are equal. */
361 #define ASSERT_NE(VAL1, VAL2) \
362 SELFTEST_BEGIN_STMT \
363 const char *desc_ = "ASSERT_NE (" #VAL1 ", " #VAL2 ")"; \
364 if ((VAL1) != (VAL2)) \
365 ::selftest::pass (SELFTEST_LOCATION, desc_); \
367 ::selftest::fail (SELFTEST_LOCATION, desc_); \
370 /* Like ASSERT_NE, but treat LOC as the effective location of the
373 #define ASSERT_NE_AT(LOC, VAL1, VAL2) \
374 SELFTEST_BEGIN_STMT \
375 const char *desc_ = "ASSERT_NE (" #VAL1 ", " #VAL2 ")"; \
376 if ((VAL1) != (VAL2)) \
377 ::selftest::pass ((LOC), desc_); \
379 ::selftest::fail ((LOC), desc_); \
382 /* Evaluate VAL1 and VAL2 and compare them with maybe_ne, calling
383 ::selftest::pass if they might be non-equal,
384 ::selftest::fail if they are known to be equal. */
386 #define ASSERT_MAYBE_NE(VAL1, VAL2) \
387 ASSERT_MAYBE_NE_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
389 /* Like ASSERT_MAYBE_NE, but treat LOC as the effective location of the
392 #define ASSERT_MAYBE_NE_AT(LOC, VAL1, VAL2) \
393 SELFTEST_BEGIN_STMT \
394 const char *desc = "ASSERT_MAYBE_NE (" #VAL1 ", " #VAL2 ")"; \
395 if (maybe_ne (VAL1, VAL2)) \
396 ::selftest::pass ((LOC), desc); \
398 ::selftest::fail ((LOC), desc); \
401 /* Evaluate LHS and RHS and compare them with >, calling
402 ::selftest::pass if LHS > RHS,
403 ::selftest::fail otherwise. */
405 #define ASSERT_GT(LHS, RHS) \
406 ASSERT_GT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
408 /* Like ASSERT_GT, but treat LOC as the effective location of the
411 #define ASSERT_GT_AT(LOC, LHS, RHS) \
412 SELFTEST_BEGIN_STMT \
413 const char *desc_ = "ASSERT_GT (" #LHS ", " #RHS ")"; \
415 ::selftest::pass ((LOC), desc_); \
417 ::selftest::fail ((LOC), desc_); \
420 /* Evaluate LHS and RHS and compare them with <, calling
421 ::selftest::pass if LHS < RHS,
422 ::selftest::fail otherwise. */
424 #define ASSERT_LT(LHS, RHS) \
425 ASSERT_LT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
427 /* Like ASSERT_LT, but treat LOC as the effective location of the
430 #define ASSERT_LT_AT(LOC, LHS, RHS) \
431 SELFTEST_BEGIN_STMT \
432 const char *desc_ = "ASSERT_LT (" #LHS ", " #RHS ")"; \
434 ::selftest::pass ((LOC), desc_); \
436 ::selftest::fail ((LOC), desc_); \
439 /* Evaluate VAL1 and VAL2 and compare them with strcmp, calling
440 ::selftest::pass if they are equal (and both are non-NULL),
441 ::selftest::fail if they are non-equal, or are both NULL. */
443 #define ASSERT_STREQ(VAL1, VAL2) \
444 SELFTEST_BEGIN_STMT \
445 ::selftest::assert_streq (SELFTEST_LOCATION, #VAL1, #VAL2, \
449 /* Like ASSERT_STREQ, but treat LOC as the effective location of the
452 #define ASSERT_STREQ_AT(LOC, VAL1, VAL2) \
453 SELFTEST_BEGIN_STMT \
454 ::selftest::assert_streq ((LOC), #VAL1, #VAL2, \
458 /* Evaluate HAYSTACK and NEEDLE and use strstr to determine if NEEDLE
460 ::selftest::pass if NEEDLE is found.
461 ::selftest::fail if it is not found. */
463 #define ASSERT_STR_CONTAINS(HAYSTACK, NEEDLE) \
464 SELFTEST_BEGIN_STMT \
465 ::selftest::assert_str_contains (SELFTEST_LOCATION, #HAYSTACK, #NEEDLE, \
466 (HAYSTACK), (NEEDLE)); \
469 /* Like ASSERT_STR_CONTAINS, but treat LOC as the effective location of the
472 #define ASSERT_STR_CONTAINS_AT(LOC, HAYSTACK, NEEDLE) \
473 SELFTEST_BEGIN_STMT \
474 ::selftest::assert_str_contains (LOC, #HAYSTACK, #NEEDLE, \
475 (HAYSTACK), (NEEDLE)); \
478 /* Evaluate STR and PREFIX and determine if STR starts with PREFIX.
479 ::selftest::pass if STR does start with PREFIX.
480 ::selftest::fail if does not, or either is NULL. */
482 #define ASSERT_STR_STARTSWITH(STR, PREFIX) \
483 SELFTEST_BEGIN_STMT \
484 ::selftest::assert_str_startswith (SELFTEST_LOCATION, #STR, #PREFIX, \
488 /* Evaluate PRED1 (VAL1), calling ::selftest::pass if it is true,
489 ::selftest::fail if it is false. */
491 #define ASSERT_PRED1(PRED1, VAL1) \
492 SELFTEST_BEGIN_STMT \
493 const char *desc_ = "ASSERT_PRED1 (" #PRED1 ", " #VAL1 ")"; \
494 bool actual_ = (PRED1) (VAL1); \
496 ::selftest::pass (SELFTEST_LOCATION, desc_); \
498 ::selftest::fail (SELFTEST_LOCATION, desc_); \
501 #define SELFTEST_BEGIN_STMT do {
502 #define SELFTEST_END_STMT } while (0)
504 #endif /* #if CHECKING_P */
506 #endif /* GCC_SELFTEST_H */