Home | History | Annotate | Line # | Download | only in gcc
selftest.h revision 1.1.1.2
      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