1 /* A self-testing framework, for use by -fself-test.
2    Copyright (C) 2015-2018 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 struct location
34 {
locationlocation35   location (const char *file, int line, const char *function)
36     : m_file (file), m_line (line), m_function (function) {}
37 
38   const char *m_file;
39   int m_line;
40   const char *m_function;
41 };
42 
43 /* A macro for use in selftests and by the ASSERT_ macros below,
44    constructing a selftest::location for the current source location.  */
45 
46 #define SELFTEST_LOCATION \
47   (::selftest::location (__FILE__, __LINE__, __FUNCTION__))
48 
49 /* The entrypoint for running all tests.  */
50 
51 extern void run_tests ();
52 
53 /* Record the successful outcome of some aspect of the test.  */
54 
55 extern void pass (const location &loc, const char *msg);
56 
57 /* Report the failed outcome of some aspect of the test and abort.  */
58 
59 extern void fail (const location &loc, const char *msg)
60   ATTRIBUTE_NORETURN;
61 
62 /* As "fail", but using printf-style formatted output.  */
63 
64 extern void fail_formatted (const location &loc, const char *fmt, ...)
65   ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
66 
67 /* Implementation detail of ASSERT_STREQ.  */
68 
69 extern void assert_streq (const location &loc,
70 			  const char *desc_expected, const char *desc_actual,
71 			  const char *val_expected, const char *val_actual);
72 
73 /* Implementation detail of ASSERT_STR_CONTAINS.  */
74 
75 extern void assert_str_contains (const location &loc,
76 				 const char *desc_haystack,
77 				 const char *desc_needle,
78 				 const char *val_haystack,
79 				 const char *val_needle);
80 
81 /* A named temporary file for use in selftests.
82    Usable for writing out files, and as the base class for
83    temp_source_file.
84    The file is unlinked in the destructor.  */
85 
86 class named_temp_file
87 {
88  public:
89   named_temp_file (const char *suffix);
90   ~named_temp_file ();
get_filename()91   const char *get_filename () const { return m_filename; }
92 
93  private:
94   char *m_filename;
95 };
96 
97 /* A class for writing out a temporary sourcefile for use in selftests
98    of input handling.  */
99 
100 class temp_source_file : public named_temp_file
101 {
102  public:
103   temp_source_file (const location &loc, const char *suffix,
104 		    const char *content);
105 };
106 
107 /* Various selftests involving location-handling require constructing a
108    line table and one or more line maps within it.
109 
110    For maximum test coverage we want to run these tests with a variety
111    of situations:
112    - line_table->default_range_bits: some frontends use a non-zero value
113    and others use zero
114    - the fallback modes within line-map.c: there are various threshold
115    values for source_location/location_t beyond line-map.c changes
116    behavior (disabling of the range-packing optimization, disabling
117    of column-tracking).  We can exercise these by starting the line_table
118    at interesting values at or near these thresholds.
119 
120    The following struct describes a particular case within our test
121    matrix.  */
122 
123 struct line_table_case;
124 
125 /* A class for overriding the global "line_table" within a selftest,
126    restoring its value afterwards.  At most one instance of this
127    class can exist at once, due to the need to keep the old value
128    of line_table as a GC root.  */
129 
130 class line_table_test
131 {
132  public:
133   /* Default constructor.  Override "line_table", using sane defaults
134      for the temporary line_table.  */
135   line_table_test ();
136 
137   /* Constructor.  Override "line_table", using the case described by C.  */
138   line_table_test (const line_table_case &c);
139 
140   /* Destructor.  Restore the saved line_table.  */
141   ~line_table_test ();
142 };
143 
144 /* Run TESTCASE multiple times, once for each case in our test matrix.  */
145 
146 extern void
147 for_each_line_table_case (void (*testcase) (const line_table_case &));
148 
149 /* Read the contents of PATH into memory, returning a 0-terminated buffer
150    that must be freed by the caller.
151    Fail (and abort) if there are any problems, with LOC as the reported
152    location of the failure.  */
153 
154 extern char *read_file (const location &loc, const char *path);
155 
156 /* A helper function for writing tests that interact with the
157    garbage collector.  */
158 
159 extern void forcibly_ggc_collect ();
160 
161 /* Convert a path relative to SRCDIR/gcc/testsuite/selftests
162    to a real path (either absolute, or relative to pwd).
163    The result should be freed by the caller.  */
164 
165 extern char *locate_file (const char *path);
166 
167 /* The path of SRCDIR/testsuite/selftests.  */
168 
169 extern const char *path_to_selftest_files;
170 
171 /* selftest::test_runner is an implementation detail of selftest::run_tests,
172    exposed here to allow plugins to run their own suites of tests.  */
173 
174 class test_runner
175 {
176  public:
177   test_runner (const char *name);
178   ~test_runner ();
179 
180  private:
181   const char *m_name;
182   long m_start_time;
183 };
184 
185 /* Declarations for specific families of tests (by source file), in
186    alphabetical order.  */
187 extern void attribute_c_tests ();
188 extern void bitmap_c_tests ();
189 extern void sbitmap_c_tests ();
190 extern void diagnostic_c_tests ();
191 extern void diagnostic_show_locus_c_tests ();
192 extern void edit_context_c_tests ();
193 extern void et_forest_c_tests ();
194 extern void fold_const_c_tests ();
195 extern void fibonacci_heap_c_tests ();
196 extern void function_tests_c_tests ();
197 extern void gimple_c_tests ();
198 extern void ggc_tests_c_tests ();
199 extern void hash_map_tests_c_tests ();
200 extern void hash_set_tests_c_tests ();
201 extern void input_c_tests ();
202 extern void pretty_print_c_tests ();
203 extern void read_rtl_function_c_tests ();
204 extern void rtl_tests_c_tests ();
205 extern void selftest_c_tests ();
206 extern void spellcheck_c_tests ();
207 extern void spellcheck_tree_c_tests ();
208 extern void sreal_c_tests ();
209 extern void store_merging_c_tests ();
210 extern void typed_splay_tree_c_tests ();
211 extern void tree_c_tests ();
212 extern void tree_cfg_c_tests ();
213 extern void unique_ptr_tests_cc_tests ();
214 extern void vec_c_tests ();
215 extern void wide_int_cc_tests ();
216 extern void predict_c_tests ();
217 extern void simplify_rtx_c_tests ();
218 extern void vec_perm_indices_c_tests ();
219 
220 extern int num_passes;
221 
222 } /* end of namespace selftest.  */
223 
224 /* Macros for writing tests.  */
225 
226 /* Evaluate EXPR and coerce to bool, calling
227    ::selftest::pass if it is true,
228    ::selftest::fail if it false.  */
229 
230 #define ASSERT_TRUE(EXPR)				\
231   ASSERT_TRUE_AT (SELFTEST_LOCATION, (EXPR))
232 
233 /* Like ASSERT_TRUE, but treat LOC as the effective location of the
234    selftest.  */
235 
236 #define ASSERT_TRUE_AT(LOC, EXPR)			\
237   SELFTEST_BEGIN_STMT					\
238   const char *desc_ = "ASSERT_TRUE (" #EXPR ")";	\
239   bool actual_ = (EXPR);				\
240   if (actual_)						\
241     ::selftest::pass ((LOC), desc_);			\
242   else							\
243     ::selftest::fail ((LOC), desc_);			\
244   SELFTEST_END_STMT
245 
246 /* Evaluate EXPR and coerce to bool, calling
247    ::selftest::pass if it is false,
248    ::selftest::fail if it true.  */
249 
250 #define ASSERT_FALSE(EXPR)					\
251   ASSERT_FALSE_AT (SELFTEST_LOCATION, (EXPR))
252 
253 /* Like ASSERT_FALSE, but treat LOC as the effective location of the
254    selftest.  */
255 
256 #define ASSERT_FALSE_AT(LOC, EXPR)				\
257   SELFTEST_BEGIN_STMT						\
258   const char *desc_ = "ASSERT_FALSE (" #EXPR ")";		\
259   bool actual_ = (EXPR);					\
260   if (actual_)							\
261     ::selftest::fail ((LOC), desc_);				\
262   else								\
263     ::selftest::pass ((LOC), desc_);				\
264   SELFTEST_END_STMT
265 
266 /* Evaluate EXPECTED and ACTUAL and compare them with ==, calling
267    ::selftest::pass if they are equal,
268    ::selftest::fail if they are non-equal.  */
269 
270 #define ASSERT_EQ(EXPECTED, ACTUAL) \
271   ASSERT_EQ_AT ((SELFTEST_LOCATION), (EXPECTED), (ACTUAL))
272 
273 /* Like ASSERT_EQ, but treat LOC as the effective location of the
274    selftest.  */
275 
276 #define ASSERT_EQ_AT(LOC, EXPECTED, ACTUAL)		       \
277   SELFTEST_BEGIN_STMT					       \
278   const char *desc_ = "ASSERT_EQ (" #EXPECTED ", " #ACTUAL ")"; \
279   if ((EXPECTED) == (ACTUAL))				       \
280     ::selftest::pass ((LOC), desc_);			       \
281   else							       \
282     ::selftest::fail ((LOC), desc_);			       \
283   SELFTEST_END_STMT
284 
285 /* Evaluate EXPECTED and ACTUAL and compare them with known_eq, calling
286    ::selftest::pass if they are always equal,
287    ::selftest::fail if they might be non-equal.  */
288 
289 #define ASSERT_KNOWN_EQ(EXPECTED, ACTUAL) \
290   ASSERT_KNOWN_EQ_AT ((SELFTEST_LOCATION), (EXPECTED), (ACTUAL))
291 
292 /* Like ASSERT_KNOWN_EQ, but treat LOC as the effective location of the
293    selftest.  */
294 
295 #define ASSERT_KNOWN_EQ_AT(LOC, EXPECTED, ACTUAL)			\
296   SELFTEST_BEGIN_STMT							\
297   const char *desc = "ASSERT_KNOWN_EQ (" #EXPECTED ", " #ACTUAL ")";	\
298   if (known_eq (EXPECTED, ACTUAL))					\
299     ::selftest::pass ((LOC), desc);					\
300   else									\
301     ::selftest::fail ((LOC), desc);					\
302   SELFTEST_END_STMT
303 
304 /* Evaluate EXPECTED and ACTUAL and compare them with !=, calling
305    ::selftest::pass if they are non-equal,
306    ::selftest::fail if they are equal.  */
307 
308 #define ASSERT_NE(EXPECTED, ACTUAL)			       \
309   SELFTEST_BEGIN_STMT					       \
310   const char *desc_ = "ASSERT_NE (" #EXPECTED ", " #ACTUAL ")"; \
311   if ((EXPECTED) != (ACTUAL))				       \
312     ::selftest::pass (SELFTEST_LOCATION, desc_);	       \
313   else							       \
314     ::selftest::fail (SELFTEST_LOCATION, desc_);	       \
315   SELFTEST_END_STMT
316 
317 /* Evaluate EXPECTED and ACTUAL and compare them with maybe_ne, calling
318    ::selftest::pass if they might be non-equal,
319    ::selftest::fail if they are known to be equal.  */
320 
321 #define ASSERT_MAYBE_NE(EXPECTED, ACTUAL) \
322   ASSERT_MAYBE_NE_AT ((SELFTEST_LOCATION), (EXPECTED), (ACTUAL))
323 
324 /* Like ASSERT_MAYBE_NE, but treat LOC as the effective location of the
325    selftest.  */
326 
327 #define ASSERT_MAYBE_NE_AT(LOC, EXPECTED, ACTUAL)			\
328   SELFTEST_BEGIN_STMT							\
329   const char *desc = "ASSERT_MAYBE_NE (" #EXPECTED ", " #ACTUAL ")";	\
330   if (maybe_ne (EXPECTED, ACTUAL))					\
331     ::selftest::pass ((LOC), desc);					\
332   else									\
333     ::selftest::fail ((LOC), desc);					\
334   SELFTEST_END_STMT
335 
336 /* Evaluate LHS and RHS and compare them with >, calling
337    ::selftest::pass if LHS > RHS,
338    ::selftest::fail otherwise.  */
339 
340 #define ASSERT_GT(LHS, RHS)				\
341   ASSERT_GT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
342 
343 /* Like ASSERT_GT, but treat LOC as the effective location of the
344    selftest.  */
345 
346 #define ASSERT_GT_AT(LOC, LHS, RHS)		       \
347   SELFTEST_BEGIN_STMT					       \
348   const char *desc_ = "ASSERT_GT (" #LHS ", " #RHS ")";	       \
349   if ((LHS) > (RHS))					       \
350     ::selftest::pass ((LOC), desc_);			       \
351   else							       \
352     ::selftest::fail ((LOC), desc_);			       \
353   SELFTEST_END_STMT
354 
355 /* Evaluate LHS and RHS and compare them with <, calling
356    ::selftest::pass if LHS < RHS,
357    ::selftest::fail otherwise.  */
358 
359 #define ASSERT_LT(LHS, RHS)				\
360   ASSERT_LT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
361 
362 /* Like ASSERT_LT, but treat LOC as the effective location of the
363    selftest.  */
364 
365 #define ASSERT_LT_AT(LOC, LHS, RHS)		       \
366   SELFTEST_BEGIN_STMT					       \
367   const char *desc_ = "ASSERT_LT (" #LHS ", " #RHS ")";	       \
368   if ((LHS) < (RHS))					       \
369     ::selftest::pass ((LOC), desc_);			       \
370   else							       \
371     ::selftest::fail ((LOC), desc_);			       \
372   SELFTEST_END_STMT
373 
374 /* Evaluate EXPECTED and ACTUAL and compare them with strcmp, calling
375    ::selftest::pass if they are equal,
376    ::selftest::fail if they are non-equal.  */
377 
378 #define ASSERT_STREQ(EXPECTED, ACTUAL)				    \
379   SELFTEST_BEGIN_STMT						    \
380   ::selftest::assert_streq (SELFTEST_LOCATION, #EXPECTED, #ACTUAL, \
381 			    (EXPECTED), (ACTUAL));		    \
382   SELFTEST_END_STMT
383 
384 /* Like ASSERT_STREQ, but treat LOC as the effective location of the
385    selftest.  */
386 
387 #define ASSERT_STREQ_AT(LOC, EXPECTED, ACTUAL)			    \
388   SELFTEST_BEGIN_STMT						    \
389   ::selftest::assert_streq ((LOC), #EXPECTED, #ACTUAL,		    \
390 			    (EXPECTED), (ACTUAL));		    \
391   SELFTEST_END_STMT
392 
393 /* Evaluate HAYSTACK and NEEDLE and use strstr to determine if NEEDLE
394    is within HAYSTACK.
395    ::selftest::pass if NEEDLE is found.
396    ::selftest::fail if it is not found.  */
397 
398 #define ASSERT_STR_CONTAINS(HAYSTACK, NEEDLE)				\
399   SELFTEST_BEGIN_STMT							\
400   ::selftest::assert_str_contains (SELFTEST_LOCATION, #HAYSTACK, #NEEDLE, \
401 				   (HAYSTACK), (NEEDLE));		\
402   SELFTEST_END_STMT
403 
404 /* Evaluate PRED1 (VAL1), calling ::selftest::pass if it is true,
405    ::selftest::fail if it is false.  */
406 
407 #define ASSERT_PRED1(PRED1, VAL1)				\
408   SELFTEST_BEGIN_STMT						\
409   const char *desc_ = "ASSERT_PRED1 (" #PRED1 ", " #VAL1 ")";	\
410   bool actual_ = (PRED1) (VAL1);				\
411   if (actual_)							\
412     ::selftest::pass (SELFTEST_LOCATION, desc_);		\
413   else								\
414     ::selftest::fail (SELFTEST_LOCATION, desc_);		\
415   SELFTEST_END_STMT
416 
417 #define SELFTEST_BEGIN_STMT do {
418 #define SELFTEST_END_STMT   } while (0)
419 
420 #endif /* #if CHECKING_P */
421 
422 #endif /* GCC_SELFTEST_H */
423