Home | History | Annotate | Line # | Download | only in gcc
selftest.h revision 1.1.1.3
      1 /* A self-testing framework, for use by -fself-test.
      2    Copyright (C) 2015-2019 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_val1, const char *desc_val2,
     71 			  const char *val1, const char *val2);
     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 /* Implementation detail of ASSERT_STR_STARTSWITH.  */
     82 
     83 extern void assert_str_startswith (const location &loc,
     84 				   const char *desc_str,
     85 				   const char *desc_prefix,
     86 				   const char *val_str,
     87 				   const char *val_prefix);
     88 
     89 
     90 /* A named temporary file for use in selftests.
     91    Usable for writing out files, and as the base class for
     92    temp_source_file.
     93    The file is unlinked in the destructor.  */
     94 
     95 class named_temp_file
     96 {
     97  public:
     98   named_temp_file (const char *suffix);
     99   ~named_temp_file ();
    100   const char *get_filename () const { return m_filename; }
    101 
    102  private:
    103   char *m_filename;
    104 };
    105 
    106 /* A class for writing out a temporary sourcefile for use in selftests
    107    of input handling.  */
    108 
    109 class temp_source_file : public named_temp_file
    110 {
    111  public:
    112   temp_source_file (const location &loc, const char *suffix,
    113 		    const char *content);
    114 };
    115 
    116 /* RAII-style class for avoiding introducing locale-specific differences
    117    in strings containing localized quote marks, by temporarily overriding
    118    the "open_quote" and "close_quote" globals to something hardcoded.
    119 
    120    Specifically, the C locale's values are used:
    121    - open_quote becomes "`"
    122    - close_quote becomes "'"
    123    for the lifetime of the object.  */
    124 
    125 class auto_fix_quotes
    126 {
    127  public:
    128   auto_fix_quotes ();
    129   ~auto_fix_quotes ();
    130 
    131  private:
    132   const char *m_saved_open_quote;
    133   const char *m_saved_close_quote;
    134 };
    135 
    136 /* Various selftests involving location-handling require constructing a
    137    line table and one or more line maps within it.
    138 
    139    For maximum test coverage we want to run these tests with a variety
    140    of situations:
    141    - line_table->default_range_bits: some frontends use a non-zero value
    142    and others use zero
    143    - the fallback modes within line-map.c: there are various threshold
    144    values for location_t beyond line-map.c changes
    145    behavior (disabling of the range-packing optimization, disabling
    146    of column-tracking).  We can exercise these by starting the line_table
    147    at interesting values at or near these thresholds.
    148 
    149    The following struct describes a particular case within our test
    150    matrix.  */
    151 
    152 struct line_table_case;
    153 
    154 /* A class for overriding the global "line_table" within a selftest,
    155    restoring its value afterwards.  At most one instance of this
    156    class can exist at once, due to the need to keep the old value
    157    of line_table as a GC root.  */
    158 
    159 class line_table_test
    160 {
    161  public:
    162   /* Default constructor.  Override "line_table", using sane defaults
    163      for the temporary line_table.  */
    164   line_table_test ();
    165 
    166   /* Constructor.  Override "line_table", using the case described by C.  */
    167   line_table_test (const line_table_case &c);
    168 
    169   /* Destructor.  Restore the saved line_table.  */
    170   ~line_table_test ();
    171 };
    172 
    173 /* Run TESTCASE multiple times, once for each case in our test matrix.  */
    174 
    175 extern void
    176 for_each_line_table_case (void (*testcase) (const line_table_case &));
    177 
    178 /* Read the contents of PATH into memory, returning a 0-terminated buffer
    179    that must be freed by the caller.
    180    Fail (and abort) if there are any problems, with LOC as the reported
    181    location of the failure.  */
    182 
    183 extern char *read_file (const location &loc, const char *path);
    184 
    185 /* A helper function for writing tests that interact with the
    186    garbage collector.  */
    187 
    188 extern void forcibly_ggc_collect ();
    189 
    190 /* Convert a path relative to SRCDIR/gcc/testsuite/selftests
    191    to a real path (either absolute, or relative to pwd).
    192    The result should be freed by the caller.  */
    193 
    194 extern char *locate_file (const char *path);
    195 
    196 /* The path of SRCDIR/testsuite/selftests.  */
    197 
    198 extern const char *path_to_selftest_files;
    199 
    200 /* selftest::test_runner is an implementation detail of selftest::run_tests,
    201    exposed here to allow plugins to run their own suites of tests.  */
    202 
    203 class test_runner
    204 {
    205  public:
    206   test_runner (const char *name);
    207   ~test_runner ();
    208 
    209  private:
    210   const char *m_name;
    211   long m_start_time;
    212 };
    213 
    214 /* Declarations for specific families of tests (by source file), in
    215    alphabetical order.  */
    216 extern void attribute_c_tests ();
    217 extern void bitmap_c_tests ();
    218 extern void cgraph_c_tests ();
    219 extern void convert_c_tests ();
    220 extern void diagnostic_c_tests ();
    221 extern void diagnostic_show_locus_c_tests ();
    222 extern void dumpfile_c_tests ();
    223 extern void edit_context_c_tests ();
    224 extern void et_forest_c_tests ();
    225 extern void fibonacci_heap_c_tests ();
    226 extern void fold_const_c_tests ();
    227 extern void function_tests_c_tests ();
    228 extern void ggc_tests_c_tests ();
    229 extern void gimple_c_tests ();
    230 extern void hash_map_tests_c_tests ();
    231 extern void hash_set_tests_c_tests ();
    232 extern void input_c_tests ();
    233 extern void json_cc_tests ();
    234 extern void opt_problem_cc_tests ();
    235 extern void optinfo_emit_json_cc_tests ();
    236 extern void predict_c_tests ();
    237 extern void pretty_print_c_tests ();
    238 extern void read_rtl_function_c_tests ();
    239 extern void rtl_tests_c_tests ();
    240 extern void sbitmap_c_tests ();
    241 extern void selftest_c_tests ();
    242 extern void simplify_rtx_c_tests ();
    243 extern void spellcheck_c_tests ();
    244 extern void spellcheck_tree_c_tests ();
    245 extern void sreal_c_tests ();
    246 extern void store_merging_c_tests ();
    247 extern void tree_c_tests ();
    248 extern void tree_cfg_c_tests ();
    249 extern void typed_splay_tree_c_tests ();
    250 extern void unique_ptr_tests_cc_tests ();
    251 extern void vec_c_tests ();
    252 extern void vec_perm_indices_c_tests ();
    253 extern void wide_int_cc_tests ();
    254 extern void opt_proposer_c_tests ();
    255 
    256 extern int num_passes;
    257 
    258 } /* end of namespace selftest.  */
    259 
    260 /* Macros for writing tests.  */
    261 
    262 /* Evaluate EXPR and coerce to bool, calling
    263    ::selftest::pass if it is true,
    264    ::selftest::fail if it false.  */
    265 
    266 #define ASSERT_TRUE(EXPR)				\
    267   ASSERT_TRUE_AT (SELFTEST_LOCATION, (EXPR))
    268 
    269 /* Like ASSERT_TRUE, but treat LOC as the effective location of the
    270    selftest.  */
    271 
    272 #define ASSERT_TRUE_AT(LOC, EXPR)			\
    273   SELFTEST_BEGIN_STMT					\
    274   const char *desc_ = "ASSERT_TRUE (" #EXPR ")";	\
    275   bool actual_ = (EXPR);				\
    276   if (actual_)						\
    277     ::selftest::pass ((LOC), desc_);			\
    278   else							\
    279     ::selftest::fail ((LOC), desc_);			\
    280   SELFTEST_END_STMT
    281 
    282 /* Evaluate EXPR and coerce to bool, calling
    283    ::selftest::pass if it is false,
    284    ::selftest::fail if it true.  */
    285 
    286 #define ASSERT_FALSE(EXPR)					\
    287   ASSERT_FALSE_AT (SELFTEST_LOCATION, (EXPR))
    288 
    289 /* Like ASSERT_FALSE, but treat LOC as the effective location of the
    290    selftest.  */
    291 
    292 #define ASSERT_FALSE_AT(LOC, EXPR)				\
    293   SELFTEST_BEGIN_STMT						\
    294   const char *desc_ = "ASSERT_FALSE (" #EXPR ")";		\
    295   bool actual_ = (EXPR);					\
    296   if (actual_)							\
    297     ::selftest::fail ((LOC), desc_);				\
    298   else								\
    299     ::selftest::pass ((LOC), desc_);				\
    300   SELFTEST_END_STMT
    301 
    302 /* Evaluate VAL1 and VAL2 and compare them with ==, calling
    303    ::selftest::pass if they are equal,
    304    ::selftest::fail if they are non-equal.  */
    305 
    306 #define ASSERT_EQ(VAL1, VAL2) \
    307   ASSERT_EQ_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
    308 
    309 /* Like ASSERT_EQ, but treat LOC as the effective location of the
    310    selftest.  */
    311 
    312 #define ASSERT_EQ_AT(LOC, VAL1, VAL2)		       \
    313   SELFTEST_BEGIN_STMT					       \
    314   const char *desc_ = "ASSERT_EQ (" #VAL1 ", " #VAL2 ")"; \
    315   if ((VAL1) == (VAL2))				       \
    316     ::selftest::pass ((LOC), desc_);			       \
    317   else							       \
    318     ::selftest::fail ((LOC), desc_);			       \
    319   SELFTEST_END_STMT
    320 
    321 /* Evaluate VAL1 and VAL2 and compare them with known_eq, calling
    322    ::selftest::pass if they are always equal,
    323    ::selftest::fail if they might be non-equal.  */
    324 
    325 #define ASSERT_KNOWN_EQ(VAL1, VAL2) \
    326   ASSERT_KNOWN_EQ_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
    327 
    328 /* Like ASSERT_KNOWN_EQ, but treat LOC as the effective location of the
    329    selftest.  */
    330 
    331 #define ASSERT_KNOWN_EQ_AT(LOC, VAL1, VAL2)			\
    332   SELFTEST_BEGIN_STMT							\
    333   const char *desc = "ASSERT_KNOWN_EQ (" #VAL1 ", " #VAL2 ")";	\
    334   if (known_eq (VAL1, VAL2))					\
    335     ::selftest::pass ((LOC), desc);					\
    336   else									\
    337     ::selftest::fail ((LOC), desc);					\
    338   SELFTEST_END_STMT
    339 
    340 /* Evaluate VAL1 and VAL2 and compare them with !=, calling
    341    ::selftest::pass if they are non-equal,
    342    ::selftest::fail if they are equal.  */
    343 
    344 #define ASSERT_NE(VAL1, VAL2)			       \
    345   SELFTEST_BEGIN_STMT					       \
    346   const char *desc_ = "ASSERT_NE (" #VAL1 ", " #VAL2 ")"; \
    347   if ((VAL1) != (VAL2))				       \
    348     ::selftest::pass (SELFTEST_LOCATION, desc_);	       \
    349   else							       \
    350     ::selftest::fail (SELFTEST_LOCATION, desc_);	       \
    351   SELFTEST_END_STMT
    352 
    353 /* Evaluate VAL1 and VAL2 and compare them with maybe_ne, calling
    354    ::selftest::pass if they might be non-equal,
    355    ::selftest::fail if they are known to be equal.  */
    356 
    357 #define ASSERT_MAYBE_NE(VAL1, VAL2) \
    358   ASSERT_MAYBE_NE_AT ((SELFTEST_LOCATION), (VAL1), (VAL2))
    359 
    360 /* Like ASSERT_MAYBE_NE, but treat LOC as the effective location of the
    361    selftest.  */
    362 
    363 #define ASSERT_MAYBE_NE_AT(LOC, VAL1, VAL2)			\
    364   SELFTEST_BEGIN_STMT							\
    365   const char *desc = "ASSERT_MAYBE_NE (" #VAL1 ", " #VAL2 ")";	\
    366   if (maybe_ne (VAL1, VAL2))					\
    367     ::selftest::pass ((LOC), desc);					\
    368   else									\
    369     ::selftest::fail ((LOC), desc);					\
    370   SELFTEST_END_STMT
    371 
    372 /* Evaluate LHS and RHS and compare them with >, calling
    373    ::selftest::pass if LHS > RHS,
    374    ::selftest::fail otherwise.  */
    375 
    376 #define ASSERT_GT(LHS, RHS)				\
    377   ASSERT_GT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
    378 
    379 /* Like ASSERT_GT, but treat LOC as the effective location of the
    380    selftest.  */
    381 
    382 #define ASSERT_GT_AT(LOC, LHS, RHS)		       \
    383   SELFTEST_BEGIN_STMT					       \
    384   const char *desc_ = "ASSERT_GT (" #LHS ", " #RHS ")";	       \
    385   if ((LHS) > (RHS))					       \
    386     ::selftest::pass ((LOC), desc_);			       \
    387   else							       \
    388     ::selftest::fail ((LOC), desc_);			       \
    389   SELFTEST_END_STMT
    390 
    391 /* Evaluate LHS and RHS and compare them with <, calling
    392    ::selftest::pass if LHS < RHS,
    393    ::selftest::fail otherwise.  */
    394 
    395 #define ASSERT_LT(LHS, RHS)				\
    396   ASSERT_LT_AT ((SELFTEST_LOCATION), (LHS), (RHS))
    397 
    398 /* Like ASSERT_LT, but treat LOC as the effective location of the
    399    selftest.  */
    400 
    401 #define ASSERT_LT_AT(LOC, LHS, RHS)		       \
    402   SELFTEST_BEGIN_STMT					       \
    403   const char *desc_ = "ASSERT_LT (" #LHS ", " #RHS ")";	       \
    404   if ((LHS) < (RHS))					       \
    405     ::selftest::pass ((LOC), desc_);			       \
    406   else							       \
    407     ::selftest::fail ((LOC), desc_);			       \
    408   SELFTEST_END_STMT
    409 
    410 /* Evaluate VAL1 and VAL2 and compare them with strcmp, calling
    411    ::selftest::pass if they are equal (and both are non-NULL),
    412    ::selftest::fail if they are non-equal, or are both NULL.  */
    413 
    414 #define ASSERT_STREQ(VAL1, VAL2)				    \
    415   SELFTEST_BEGIN_STMT						    \
    416   ::selftest::assert_streq (SELFTEST_LOCATION, #VAL1, #VAL2, \
    417 			    (VAL1), (VAL2));		    \
    418   SELFTEST_END_STMT
    419 
    420 /* Like ASSERT_STREQ, but treat LOC as the effective location of the
    421    selftest.  */
    422 
    423 #define ASSERT_STREQ_AT(LOC, VAL1, VAL2)			    \
    424   SELFTEST_BEGIN_STMT						    \
    425   ::selftest::assert_streq ((LOC), #VAL1, #VAL2,		    \
    426 			    (VAL1), (VAL2));		    \
    427   SELFTEST_END_STMT
    428 
    429 /* Evaluate HAYSTACK and NEEDLE and use strstr to determine if NEEDLE
    430    is within HAYSTACK.
    431    ::selftest::pass if NEEDLE is found.
    432    ::selftest::fail if it is not found.  */
    433 
    434 #define ASSERT_STR_CONTAINS(HAYSTACK, NEEDLE)				\
    435   SELFTEST_BEGIN_STMT							\
    436   ::selftest::assert_str_contains (SELFTEST_LOCATION, #HAYSTACK, #NEEDLE, \
    437 				   (HAYSTACK), (NEEDLE));		\
    438   SELFTEST_END_STMT
    439 
    440 /* Like ASSERT_STR_CONTAINS, but treat LOC as the effective location of the
    441    selftest.  */
    442 
    443 #define ASSERT_STR_CONTAINS_AT(LOC, HAYSTACK, NEEDLE)			\
    444   SELFTEST_BEGIN_STMT							\
    445   ::selftest::assert_str_contains (LOC, #HAYSTACK, #NEEDLE,		\
    446 				   (HAYSTACK), (NEEDLE));		\
    447   SELFTEST_END_STMT
    448 
    449 /* Evaluate STR and PREFIX and determine if STR starts with PREFIX.
    450      ::selftest::pass if STR does start with PREFIX.
    451      ::selftest::fail if does not, or either is NULL.  */
    452 
    453 #define ASSERT_STR_STARTSWITH(STR, PREFIX)				    \
    454   SELFTEST_BEGIN_STMT							    \
    455   ::selftest::assert_str_startswith (SELFTEST_LOCATION, #STR, #PREFIX,	    \
    456 				     (STR), (PREFIX));			    \
    457   SELFTEST_END_STMT
    458 
    459 /* Evaluate PRED1 (VAL1), calling ::selftest::pass if it is true,
    460    ::selftest::fail if it is false.  */
    461 
    462 #define ASSERT_PRED1(PRED1, VAL1)				\
    463   SELFTEST_BEGIN_STMT						\
    464   const char *desc_ = "ASSERT_PRED1 (" #PRED1 ", " #VAL1 ")";	\
    465   bool actual_ = (PRED1) (VAL1);				\
    466   if (actual_)							\
    467     ::selftest::pass (SELFTEST_LOCATION, desc_);		\
    468   else								\
    469     ::selftest::fail (SELFTEST_LOCATION, desc_);		\
    470   SELFTEST_END_STMT
    471 
    472 #define SELFTEST_BEGIN_STMT do {
    473 #define SELFTEST_END_STMT   } while (0)
    474 
    475 #endif /* #if CHECKING_P */
    476 
    477 #endif /* GCC_SELFTEST_H */
    478