Commit f87e22c5 by David Malcolm Committed by David Malcolm

selftest.h: add class line_table_test

input.c has a fixture class for running each selftest with a fresh
line_table, and logic for looping over various interesting line_table
test cases.

This patch exposes the above in selftest.h so that such
location-handling tests can be written in other files, renaming the
class from temp_line_table to line_table_test.

Also, the patch moves the stored line table ptr from being a member of
the test class to being a global GC-root, to avoid it being collected
if the GC runs during such a test.

gcc/ChangeLog:
	* input.c (saved_line_table): New global.
	(class selftest::temp_line_table): Rename to line_table_test and
	move declaration to selftest.h, and drop field m_old_line_table.
	(selftest::temp_line_table::temp_line_table): Rename ctor to...
	(selftest::line_table_test::line_table_test): ...this.  Add a
	default ctor.  Store current value of line_table within
	saved_line_table.
	(selftest::temp_line_table::~temp_line_table): Rename dtor to...
	(selftest::line_table_test::~line_table_test): ...this, and
	restore line_table from the saved_line_table, rather than
	m_old_line_table.
	(selftest::test_accessing_ordinary_linemaps): Update for above
	renaming.
	(selftest::test_lexer): Likewise.
	(struct selftest::lexer_test): Likewise.
	(selftest::lexer_test::lexer_test): Likewise.
	(selftest::input_c_tests): Move the looping over test cases from
	here into...
	(selftest::for_each_line_table_case): New function.
	* input.h (saved_line_table): New decl.
	* selftest.h (struct selftest::line_table_case): New forward decl.
	(class selftest::line_table_test): New class, moved here from
	selftest::temp_line_table in input.c, and renamed.
	(selftest::for_each_line_table_case): New decl.

From-SVN: r239580
parent 89c88780
2016-08-18 David Malcolm <dmalcolm@redhat.com>
* input.c (saved_line_table): New global.
(class selftest::temp_line_table): Rename to line_table_test and
move declaration to selftest.h, and drop field m_old_line_table.
(selftest::temp_line_table::temp_line_table): Rename ctor to...
(selftest::line_table_test::line_table_test): ...this. Add a
default ctor. Store current value of line_table within
saved_line_table.
(selftest::temp_line_table::~temp_line_table): Rename dtor to...
(selftest::line_table_test::~line_table_test): ...this, and
restore line_table from the saved_line_table, rather than
m_old_line_table.
(selftest::test_accessing_ordinary_linemaps): Update for above
renaming.
(selftest::test_lexer): Likewise.
(struct selftest::lexer_test): Likewise.
(selftest::lexer_test::lexer_test): Likewise.
(selftest::input_c_tests): Move the looping over test cases from
here into...
(selftest::for_each_line_table_case): New function.
* input.h (saved_line_table): New decl.
* selftest.h (struct selftest::line_table_case): New forward decl.
(class selftest::line_table_test): New class, moved here from
selftest::temp_line_table in input.c, and renamed.
(selftest::for_each_line_table_case): New decl.
2015-08-18 H.J. Lu <hongjiu.lu@intel.com> 2015-08-18 H.J. Lu <hongjiu.lu@intel.com>
PR target/72839 PR target/72839
......
...@@ -114,6 +114,13 @@ location_t input_location = UNKNOWN_LOCATION; ...@@ -114,6 +114,13 @@ location_t input_location = UNKNOWN_LOCATION;
struct line_maps *line_table; struct line_maps *line_table;
/* A stashed copy of "line_table" for use by selftest::line_table_test.
This needs to be a global so that it can be a GC root, and thus
prevent the stashed copy from being garbage-collected if the GC runs
during a line_table_test. */
struct line_maps *saved_line_table;
static fcache *fcache_tab; static fcache *fcache_tab;
static const size_t fcache_tab_size = 16; static const size_t fcache_tab_size = 16;
static const size_t fcache_buffer_size = 4 * 1024; static const size_t fcache_buffer_size = 4 * 1024;
...@@ -1591,8 +1598,8 @@ assert_loceq (const char *exp_filename, int exp_linenum, int exp_colnum, ...@@ -1591,8 +1598,8 @@ assert_loceq (const char *exp_filename, int exp_linenum, int exp_colnum,
ASSERT_EQ (exp_colnum, LOCATION_COLUMN (loc)); ASSERT_EQ (exp_colnum, LOCATION_COLUMN (loc));
} }
/* Various selftests in this file involve constructing a line table /* Various selftests involve constructing a line table and one or more
and one or more line maps within it. line maps within it.
For maximum test coverage we want to run these tests with a variety For maximum test coverage we want to run these tests with a variety
of situations: of situations:
...@@ -1618,29 +1625,35 @@ struct line_table_case ...@@ -1618,29 +1625,35 @@ struct line_table_case
int m_base_location; int m_base_location;
}; };
/* A class for overriding the global "line_table" within a selftest, /* Constructor. Store the old value of line_table, and create a new
restoring its value afterwards. */ one, using sane defaults. */
class temp_line_table line_table_test::line_table_test ()
{ {
public: gcc_assert (saved_line_table == NULL);
temp_line_table (const line_table_case &); saved_line_table = line_table;
~temp_line_table (); line_table = ggc_alloc<line_maps> ();
linemap_init (line_table, BUILTINS_LOCATION);
private: gcc_assert (saved_line_table->reallocator);
line_maps *m_old_line_table; line_table->reallocator = saved_line_table->reallocator;
}; gcc_assert (saved_line_table->round_alloc_size);
line_table->round_alloc_size = saved_line_table->round_alloc_size;
line_table->default_range_bits = 0;
}
/* Constructor. Store the old value of line_table, and create a new /* Constructor. Store the old value of line_table, and create a new
one, using the sitation described in CASE_. */ one, using the sitation described in CASE_. */
temp_line_table::temp_line_table (const line_table_case &case_) line_table_test::line_table_test (const line_table_case &case_)
: m_old_line_table (line_table)
{ {
gcc_assert (saved_line_table == NULL);
saved_line_table = line_table;
line_table = ggc_alloc<line_maps> (); line_table = ggc_alloc<line_maps> ();
linemap_init (line_table, BUILTINS_LOCATION); linemap_init (line_table, BUILTINS_LOCATION);
line_table->reallocator = m_old_line_table->reallocator; gcc_assert (saved_line_table->reallocator);
line_table->round_alloc_size = m_old_line_table->round_alloc_size; line_table->reallocator = saved_line_table->reallocator;
gcc_assert (saved_line_table->round_alloc_size);
line_table->round_alloc_size = saved_line_table->round_alloc_size;
line_table->default_range_bits = case_.m_default_range_bits; line_table->default_range_bits = case_.m_default_range_bits;
if (case_.m_base_location) if (case_.m_base_location)
{ {
...@@ -1651,9 +1664,11 @@ temp_line_table::temp_line_table (const line_table_case &case_) ...@@ -1651,9 +1664,11 @@ temp_line_table::temp_line_table (const line_table_case &case_)
/* Destructor. Restore the old value of line_table. */ /* Destructor. Restore the old value of line_table. */
temp_line_table::~temp_line_table () line_table_test::~line_table_test ()
{ {
line_table = m_old_line_table; gcc_assert (saved_line_table != NULL);
line_table = saved_line_table;
saved_line_table = NULL;
} }
/* Verify basic operation of ordinary linemaps. */ /* Verify basic operation of ordinary linemaps. */
...@@ -1661,7 +1676,7 @@ temp_line_table::~temp_line_table () ...@@ -1661,7 +1676,7 @@ temp_line_table::~temp_line_table ()
static void static void
test_accessing_ordinary_linemaps (const line_table_case &case_) test_accessing_ordinary_linemaps (const line_table_case &case_)
{ {
temp_line_table tmp_lt (case_); line_table_test ltt (case_);
/* Build a simple linemap describing some locations. */ /* Build a simple linemap describing some locations. */
linemap_add (line_table, LC_ENTER, false, "foo.c", 0); linemap_add (line_table, LC_ENTER, false, "foo.c", 0);
...@@ -1813,7 +1828,7 @@ test_lexer (const line_table_case &case_) ...@@ -1813,7 +1828,7 @@ test_lexer (const line_table_case &case_)
" 42\n"); " 42\n");
temp_source_file tmp (SELFTEST_LOCATION, ".txt", content); temp_source_file tmp (SELFTEST_LOCATION, ".txt", content);
temp_line_table tmp_lt (case_); line_table_test ltt (case_);
cpp_reader *parser = cpp_create_reader (CLK_GNUC89, NULL, line_table); cpp_reader *parser = cpp_create_reader (CLK_GNUC89, NULL, line_table);
...@@ -1876,7 +1891,7 @@ struct lexer_test ...@@ -1876,7 +1891,7 @@ struct lexer_test
const cpp_token *get_token (); const cpp_token *get_token ();
temp_source_file m_tempfile; temp_source_file m_tempfile;
temp_line_table m_tmp_lt; line_table_test m_ltt;
cpp_reader *m_parser; cpp_reader *m_parser;
string_concat_db m_concats; string_concat_db m_concats;
}; };
...@@ -1948,7 +1963,7 @@ lexer_test::lexer_test (const line_table_case &case_, const char *content, ...@@ -1948,7 +1963,7 @@ lexer_test::lexer_test (const line_table_case &case_, const char *content,
lexer_test_options *options) : lexer_test_options *options) :
/* Create a tempfile and write the text to it. */ /* Create a tempfile and write the text to it. */
m_tempfile (SELFTEST_LOCATION, ".c", content), m_tempfile (SELFTEST_LOCATION, ".c", content),
m_tmp_lt (case_), m_ltt (case_),
m_parser (cpp_create_reader (CLK_GNUC99, NULL, line_table)), m_parser (cpp_create_reader (CLK_GNUC99, NULL, line_table)),
m_concats () m_concats ()
{ {
...@@ -3129,15 +3144,11 @@ static const location_t boundary_locations[] = { ...@@ -3129,15 +3144,11 @@ static const location_t boundary_locations[] = {
LINE_MAP_MAX_LOCATION_WITH_COLS + 0x100, LINE_MAP_MAX_LOCATION_WITH_COLS + 0x100,
}; };
/* Run all of the selftests within this file. */ /* Run TESTCASE multiple times, once for each case in our test matrix. */
void void
input_c_tests () for_each_line_table_case (void (*testcase) (const line_table_case &))
{ {
test_should_have_column_data_p ();
test_unknown_location ();
test_builtins ();
/* As noted above in the description of struct line_table_case, /* As noted above in the description of struct line_table_case,
we want to explore a test matrix of interesting line_table we want to explore a test matrix of interesting line_table
situations, running various selftests for each case within the situations, running various selftests for each case within the
...@@ -3158,30 +3169,7 @@ input_c_tests () ...@@ -3158,30 +3169,7 @@ input_c_tests ()
{ {
line_table_case c (default_range_bits, boundary_locations[loc_idx]); line_table_case c (default_range_bits, boundary_locations[loc_idx]);
/* Run all tests for the given case within the test matrix. */ testcase (c);
test_accessing_ordinary_linemaps (c);
test_lexer (c);
test_lexer_string_locations_simple (c);
test_lexer_string_locations_ebcdic (c);
test_lexer_string_locations_hex (c);
test_lexer_string_locations_oct (c);
test_lexer_string_locations_letter_escape_1 (c);
test_lexer_string_locations_letter_escape_2 (c);
test_lexer_string_locations_ucn4 (c);
test_lexer_string_locations_ucn8 (c);
test_lexer_string_locations_wide_string (c);
test_lexer_string_locations_string16 (c);
test_lexer_string_locations_string32 (c);
test_lexer_string_locations_u8 (c);
test_lexer_string_locations_utf8_source (c);
test_lexer_string_locations_concatenation_1 (c);
test_lexer_string_locations_concatenation_2 (c);
test_lexer_string_locations_concatenation_3 (c);
test_lexer_string_locations_macro (c);
test_lexer_string_locations_stringified_macro_argument (c);
test_lexer_string_locations_non_string (c);
test_lexer_string_locations_long_line (c);
test_lexer_char_constants (c);
num_cases_tested++; num_cases_tested++;
} }
...@@ -3189,6 +3177,40 @@ input_c_tests () ...@@ -3189,6 +3177,40 @@ input_c_tests ()
/* Verify that we fully covered the test matrix. */ /* Verify that we fully covered the test matrix. */
ASSERT_EQ (num_cases_tested, 2 * 12); ASSERT_EQ (num_cases_tested, 2 * 12);
}
/* Run all of the selftests within this file. */
void
input_c_tests ()
{
test_should_have_column_data_p ();
test_unknown_location ();
test_builtins ();
for_each_line_table_case (test_accessing_ordinary_linemaps);
for_each_line_table_case (test_lexer);
for_each_line_table_case (test_lexer_string_locations_simple);
for_each_line_table_case (test_lexer_string_locations_ebcdic);
for_each_line_table_case (test_lexer_string_locations_hex);
for_each_line_table_case (test_lexer_string_locations_oct);
for_each_line_table_case (test_lexer_string_locations_letter_escape_1);
for_each_line_table_case (test_lexer_string_locations_letter_escape_2);
for_each_line_table_case (test_lexer_string_locations_ucn4);
for_each_line_table_case (test_lexer_string_locations_ucn8);
for_each_line_table_case (test_lexer_string_locations_wide_string);
for_each_line_table_case (test_lexer_string_locations_string16);
for_each_line_table_case (test_lexer_string_locations_string32);
for_each_line_table_case (test_lexer_string_locations_u8);
for_each_line_table_case (test_lexer_string_locations_utf8_source);
for_each_line_table_case (test_lexer_string_locations_concatenation_1);
for_each_line_table_case (test_lexer_string_locations_concatenation_2);
for_each_line_table_case (test_lexer_string_locations_concatenation_3);
for_each_line_table_case (test_lexer_string_locations_macro);
for_each_line_table_case (test_lexer_string_locations_stringified_macro_argument);
for_each_line_table_case (test_lexer_string_locations_non_string);
for_each_line_table_case (test_lexer_string_locations_long_line);
for_each_line_table_case (test_lexer_char_constants);
test_reading_source_line (); test_reading_source_line ();
} }
......
...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "line-map.h" #include "line-map.h"
extern GTY(()) struct line_maps *line_table; extern GTY(()) struct line_maps *line_table;
extern GTY(()) struct line_maps *saved_line_table;
/* A value which will never be used to represent a real location. */ /* A value which will never be used to represent a real location. */
#define UNKNOWN_LOCATION ((source_location) 0) #define UNKNOWN_LOCATION ((source_location) 0)
......
...@@ -85,6 +85,48 @@ class temp_source_file ...@@ -85,6 +85,48 @@ class temp_source_file
char *m_filename; char *m_filename;
}; };
/* Various selftests involving location-handling require constructing a
line table and one or more line maps within it.
For maximum test coverage we want to run these tests with a variety
of situations:
- line_table->default_range_bits: some frontends use a non-zero value
and others use zero
- the fallback modes within line-map.c: there are various threshold
values for source_location/location_t beyond line-map.c changes
behavior (disabling of the range-packing optimization, disabling
of column-tracking). We can exercise these by starting the line_table
at interesting values at or near these thresholds.
The following struct describes a particular case within our test
matrix. */
struct line_table_case;
/* A class for overriding the global "line_table" within a selftest,
restoring its value afterwards. At most one instance of this
class can exist at once, due to the need to keep the old value
of line_table as a GC root. */
class line_table_test
{
public:
/* Default constructor. Override "line_table", using sane defaults
for the temporary line_table. */
line_table_test ();
/* Constructor. Override "line_table", using the case described by C. */
line_table_test (const line_table_case &c);
/* Destructor. Restore the saved line_table. */
~line_table_test ();
};
/* Run TESTCASE multiple times, once for each case in our test matrix. */
extern void
for_each_line_table_case (void (*testcase) (const line_table_case &));
/* Declarations for specific families of tests (by source file), in /* Declarations for specific families of tests (by source file), in
alphabetical order. */ alphabetical order. */
extern void bitmap_c_tests (); extern void bitmap_c_tests ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment