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 { 35 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 (); 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