Home | History | Annotate | Line # | Download | only in gcc
selftest.h revision 1.1.1.1.4.2
      1 /* A self-testing framework, for use by -fself-test.
      2    Copyright (C) 2015-2017 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 /* Declarations for specific families of tests (by source file), in
    172    alphabetical order.  */
    173 extern void bitmap_c_tests ();
    174 extern void diagnostic_c_tests ();
    175 extern void diagnostic_show_locus_c_tests ();
    176 extern void edit_context_c_tests ();
    177 extern void et_forest_c_tests ();
    178 extern void fold_const_c_tests ();
    179 extern void fibonacci_heap_c_tests ();
    180 extern void function_tests_c_tests ();
    181 extern void gimple_c_tests ();
    182 extern void ggc_tests_c_tests ();
    183 extern void hash_map_tests_c_tests ();
    184 extern void hash_set_tests_c_tests ();
    185 extern void input_c_tests ();
    186 extern void pretty_print_c_tests ();
    187 extern void read_rtl_function_c_tests ();
    188 extern void rtl_tests_c_tests ();
    189 extern void selftest_c_tests ();
    190 extern void spellcheck_c_tests ();
    191 extern void spellcheck_tree_c_tests ();
    192 extern void sreal_c_tests ();
    193 extern void store_merging_c_tests ();
    194 extern void typed_splay_tree_c_tests ();
    195 extern void tree_c_tests ();
    196 extern void tree_cfg_c_tests ();
    197 extern void vec_c_tests ();
    198 extern void wide_int_cc_tests ();
    199 
    200 extern int num_passes;
    201 
    202 } /* end of namespace selftest.  */
    203 
    204 /* Macros for writing tests.  */
    205 
    206 /* Evaluate EXPR and coerce to bool, calling
    207    ::selftest::pass if it is true,
    208    ::selftest::fail if it false.  */
    209 
    210 #define ASSERT_TRUE(EXPR)				\
    211   ASSERT_TRUE_AT (SELFTEST_LOCATION, (EXPR))
    212 
    213 /* Like ASSERT_TRUE, but treat LOC as the effective location of the
    214    selftest.  */
    215 
    216 #define ASSERT_TRUE_AT(LOC, EXPR)			\
    217   SELFTEST_BEGIN_STMT					\
    218   const char *desc = "ASSERT_TRUE (" #EXPR ")";		\
    219   bool actual = (EXPR);					\
    220   if (actual)						\
    221     ::selftest::pass ((LOC), desc);			\
    222   else							\
    223     ::selftest::fail ((LOC), desc);			\
    224   SELFTEST_END_STMT
    225 
    226 /* Evaluate EXPR and coerce to bool, calling
    227    ::selftest::pass if it is false,
    228    ::selftest::fail if it true.  */
    229 
    230 #define ASSERT_FALSE(EXPR)					\
    231   ASSERT_FALSE_AT (SELFTEST_LOCATION, (EXPR))
    232 
    233 /* Like ASSERT_FALSE, but treat LOC as the effective location of the
    234    selftest.  */
    235 
    236 #define ASSERT_FALSE_AT(LOC, EXPR)				\
    237   SELFTEST_BEGIN_STMT						\
    238   const char *desc = "ASSERT_FALSE (" #EXPR ")";			\
    239   bool actual = (EXPR);							\
    240   if (actual)								\
    241     ::selftest::fail ((LOC), desc);			\
    242   else									\
    243     ::selftest::pass ((LOC), desc);					\
    244   SELFTEST_END_STMT
    245 
    246 /* Evaluate EXPECTED and ACTUAL and compare them with ==, calling
    247    ::selftest::pass if they are equal,
    248    ::selftest::fail if they are non-equal.  */
    249 
    250 #define ASSERT_EQ(EXPECTED, ACTUAL) \
    251   ASSERT_EQ_AT ((SELFTEST_LOCATION), (EXPECTED), (ACTUAL))
    252 
    253 /* Like ASSERT_EQ, but treat LOC as the effective location of the
    254    selftest.  */
    255 
    256 #define ASSERT_EQ_AT(LOC, EXPECTED, ACTUAL)		       \
    257   SELFTEST_BEGIN_STMT					       \
    258   const char *desc = "ASSERT_EQ (" #EXPECTED ", " #ACTUAL ")"; \
    259   if ((EXPECTED) == (ACTUAL))				       \
    260     ::selftest::pass ((LOC), desc);			       \
    261   else							       \
    262     ::selftest::fail ((LOC), desc);			       \
    263   SELFTEST_END_STMT
    264 
    265 /* Evaluate EXPECTED and ACTUAL and compare them with !=, calling
    266    ::selftest::pass if they are non-equal,
    267    ::selftest::fail if they are equal.  */
    268 
    269 #define ASSERT_NE(EXPECTED, ACTUAL)			       \
    270   SELFTEST_BEGIN_STMT					       \
    271   const char *desc = "ASSERT_NE (" #EXPECTED ", " #ACTUAL ")"; \
    272   if ((EXPECTED) != (ACTUAL))				       \
    273     ::selftest::pass (SELFTEST_LOCATION, desc);			       \
    274   else							       \
    275     ::selftest::fail (SELFTEST_LOCATION, desc);			       \
    276   SELFTEST_END_STMT
    277 
    278 /* Evaluate EXPECTED and ACTUAL and compare them with strcmp, calling
    279    ::selftest::pass if they are equal,
    280    ::selftest::fail if they are non-equal.  */
    281 
    282 #define ASSERT_STREQ(EXPECTED, ACTUAL)				    \
    283   SELFTEST_BEGIN_STMT						    \
    284   ::selftest::assert_streq (SELFTEST_LOCATION, #EXPECTED, #ACTUAL, \
    285 			    (EXPECTED), (ACTUAL));		    \
    286   SELFTEST_END_STMT
    287 
    288 /* Like ASSERT_STREQ, but treat LOC as the effective location of the
    289    selftest.  */
    290 
    291 #define ASSERT_STREQ_AT(LOC, EXPECTED, ACTUAL)			    \
    292   SELFTEST_BEGIN_STMT						    \
    293   ::selftest::assert_streq ((LOC), #EXPECTED, #ACTUAL,		    \
    294 			    (EXPECTED), (ACTUAL));		    \
    295   SELFTEST_END_STMT
    296 
    297 /* Evaluate HAYSTACK and NEEDLE and use strstr to determine if NEEDLE
    298    is within HAYSTACK.
    299    ::selftest::pass if NEEDLE is found.
    300    ::selftest::fail if it is not found.  */
    301 
    302 #define ASSERT_STR_CONTAINS(HAYSTACK, NEEDLE)				\
    303   SELFTEST_BEGIN_STMT							\
    304   ::selftest::assert_str_contains (SELFTEST_LOCATION, #HAYSTACK, #NEEDLE, \
    305 				   (HAYSTACK), (NEEDLE));		\
    306   SELFTEST_END_STMT
    307 
    308 /* Evaluate PRED1 (VAL1), calling ::selftest::pass if it is true,
    309    ::selftest::fail if it is false.  */
    310 
    311 #define ASSERT_PRED1(PRED1, VAL1)			\
    312   SELFTEST_BEGIN_STMT					\
    313   const char *desc = "ASSERT_PRED1 (" #PRED1 ", " #VAL1 ")";	\
    314   bool actual = (PRED1) (VAL1);				\
    315   if (actual)						\
    316     ::selftest::pass (SELFTEST_LOCATION, desc);			\
    317   else							\
    318     ::selftest::fail (SELFTEST_LOCATION, desc);			\
    319   SELFTEST_END_STMT
    320 
    321 #define SELFTEST_BEGIN_STMT do {
    322 #define SELFTEST_END_STMT   } while (0)
    323 
    324 #endif /* #if CHECKING_P */
    325 
    326 #endif /* GCC_SELFTEST_H */
    327