From: Lewis Hyatt <lhyatt@gmail.com>
To: gcc-patches@gcc.gnu.org
Cc: David Malcolm <dmalcolm@redhat.com>, Lewis Hyatt <lhyatt@gmail.com>
Subject: [PATCH v4 5/8] diagnostics: Support testing generated data in input.cc selftests
Date: Wed, 9 Aug 2023 18:14:11 -0400 [thread overview]
Message-ID: <20230809221414.2849878-6-lhyatt@gmail.com> (raw)
In-Reply-To: <20230809221414.2849878-1-lhyatt@gmail.com>
Add selftests for the new capabilities in input.cc related to source code
locations that are stored in memory rather than ordinary files.
gcc/ChangeLog:
* input.cc (temp_source_file::do_linemap_add): New function.
(line_table_case::line_table_case): Add GENERATED_DATA argument.
(line_table_test::line_table_test): Implement new M_GENERATED_DATA
argument.
(for_each_line_table_case): Optionally include generated data
locations in the set of cases.
(test_accessing_ordinary_linemaps): Test generated data locations.
(test_make_location_nonpure_range_endpoints): Likewise.
(test_line_offset_overflow): Likewise.
(input_cc_tests): Likewise.
* selftest.cc (named_temp_file::named_temp_file): Interpret a null
SUFFIX argument as a request to use in-memory data.
(named_temp_file::~named_temp_file): Support in-memory data.
(temp_source_file::temp_source_file): Likewise.
(temp_source_file::~temp_source_file): Likewise.
* selftest.h (struct line_map_ordinary): Foward declare.
(class named_temp_file): Add missing explicit to the constructor.
(class temp_source_file): Add new members to support in-memory data.
(class line_table_test): Likewise.
(for_each_line_table_case): Adjust prototype.
---
gcc/input.cc | 81 +++++++++++++++++++++++++++++++++----------------
gcc/selftest.cc | 53 +++++++++++++++++++++++++-------
gcc/selftest.h | 19 ++++++++++--
3 files changed, 113 insertions(+), 40 deletions(-)
diff --git a/gcc/input.cc b/gcc/input.cc
index 790279d4273..8c4e40aaf23 100644
--- a/gcc/input.cc
+++ b/gcc/input.cc
@@ -2066,6 +2066,20 @@ get_num_source_ranges_for_substring (cpp_reader *pfile,
/* Selftests of location handling. */
+/* Wrapper around linemap_add to handle transparently adding either a tmp file,
+ or in-memory generated content. */
+const line_map_ordinary *
+temp_source_file::do_linemap_add (int line)
+{
+ const line_map *map;
+ if (content_buf)
+ map = linemap_add (line_table, LC_GEN, false, content_buf,
+ line, content_len);
+ else
+ map = linemap_add (line_table, LC_ENTER, false, get_filename (), line);
+ return linemap_check_ordinary (map);
+}
+
/* Verify that compare() on linenum_type handles comparisons over the full
range of the type. */
@@ -2144,13 +2158,16 @@ assert_loceq (const char *exp_filename, int exp_linenum, int exp_colnum,
class line_table_case
{
public:
- line_table_case (int default_range_bits, int base_location)
+ line_table_case (int default_range_bits, int base_location,
+ bool generated_data)
: m_default_range_bits (default_range_bits),
- m_base_location (base_location)
+ m_base_location (base_location),
+ m_generated_data (generated_data)
{}
int m_default_range_bits;
int m_base_location;
+ bool m_generated_data;
};
/* Constructor. Store the old value of line_table, and create a new
@@ -2167,6 +2184,7 @@ line_table_test::line_table_test ()
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;
+ m_generated_data = false;
}
/* Constructor. Store the old value of line_table, and create a new
@@ -2188,6 +2206,7 @@ line_table_test::line_table_test (const line_table_case &case_)
line_table->highest_location = case_.m_base_location;
line_table->highest_line = case_.m_base_location;
}
+ m_generated_data = case_.m_generated_data;
}
/* Destructor. Restore the old value of line_table. */
@@ -2207,7 +2226,10 @@ test_accessing_ordinary_linemaps (const line_table_case &case_)
line_table_test ltt (case_);
/* Build a simple linemap describing some locations. */
- linemap_add (line_table, LC_ENTER, false, "foo.c", 0);
+ if (ltt.m_generated_data)
+ linemap_add (line_table, LC_GEN, false, "some data", 0, 10);
+ else
+ linemap_add (line_table, LC_ENTER, false, "foo.c", 0);
linemap_line_start (line_table, 1, 100);
location_t loc_a = linemap_position_for_column (line_table, 1);
@@ -2257,21 +2279,23 @@ test_accessing_ordinary_linemaps (const line_table_case &case_)
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
/* Verify that we can recover the location info. */
- assert_loceq ("foo.c", 1, 1, loc_a);
- assert_loceq ("foo.c", 1, 23, loc_b);
- assert_loceq ("foo.c", 2, 1, loc_c);
- assert_loceq ("foo.c", 2, 17, loc_d);
- assert_loceq ("foo.c", 3, 700, loc_e);
- assert_loceq ("foo.c", 4, 100, loc_back_to_short);
+ const auto fname
+ = (ltt.m_generated_data ? special_fname_generated () : "foo.c");
+ assert_loceq (fname, 1, 1, loc_a);
+ assert_loceq (fname, 1, 23, loc_b);
+ assert_loceq (fname, 2, 1, loc_c);
+ assert_loceq (fname, 2, 17, loc_d);
+ assert_loceq (fname, 3, 700, loc_e);
+ assert_loceq (fname, 4, 100, loc_back_to_short);
/* In the very wide line, the initial location should be fully tracked. */
- assert_loceq ("foo.c", 5, 2000, loc_start_of_very_long_line);
+ assert_loceq (fname, 5, 2000, loc_start_of_very_long_line);
/* ...but once we exceed LINE_MAP_MAX_COLUMN_NUMBER column-tracking should
be disabled. */
- assert_loceq ("foo.c", 5, 0, loc_too_wide);
- assert_loceq ("foo.c", 5, 0, loc_too_wide_2);
+ assert_loceq (fname, 5, 0, loc_too_wide);
+ assert_loceq (fname, 5, 0, loc_too_wide_2);
/*...and column-tracking should be re-enabled for subsequent lines. */
- assert_loceq ("foo.c", 6, 10, loc_sane_again);
+ assert_loceq (fname, 6, 10, loc_sane_again);
assert_loceq ("bar.c", 1, 150, loc_f);
@@ -2318,10 +2342,11 @@ test_make_location_nonpure_range_endpoints (const line_table_case &case_)
with C++ frontend.
....................0000000001111111111222.
....................1234567890123456789012. */
- const char *content = " r += !aaa == bbb;\n";
- temp_source_file tmp (SELFTEST_LOCATION, ".C", content);
line_table_test ltt (case_);
- linemap_add (line_table, LC_ENTER, false, tmp.get_filename (), 1);
+ const char *content = " r += !aaa == bbb;\n";
+ temp_source_file tmp (SELFTEST_LOCATION, ".C", content, strlen (content),
+ ltt.m_generated_data);
+ tmp.do_linemap_add (1);
const location_t c11 = linemap_position_for_column (line_table, 11);
const location_t c12 = linemap_position_for_column (line_table, 12);
@@ -3978,7 +4003,8 @@ static const location_t boundary_locations[] = {
/* Run TESTCASE multiple times, once for each case in our test matrix. */
void
-for_each_line_table_case (void (*testcase) (const line_table_case &))
+for_each_line_table_case (void (*testcase) (const line_table_case &),
+ bool test_generated_data)
{
/* As noted above in the description of struct line_table_case,
we want to explore a test matrix of interesting line_table
@@ -3997,16 +4023,19 @@ for_each_line_table_case (void (*testcase) (const line_table_case &))
const int num_boundary_locations = ARRAY_SIZE (boundary_locations);
for (int loc_idx = 0; loc_idx < num_boundary_locations; loc_idx++)
{
- line_table_case c (default_range_bits, boundary_locations[loc_idx]);
-
- testcase (c);
-
- num_cases_tested++;
+ /* ...and try both normal files, and internally generated data. */
+ for (int gen = 0; gen != 1+test_generated_data; ++gen)
+ {
+ line_table_case c (default_range_bits,
+ boundary_locations[loc_idx], gen);
+ testcase (c);
+ num_cases_tested++;
+ }
}
}
/* Verify that we fully covered the test matrix. */
- ASSERT_EQ (num_cases_tested, 2 * 12);
+ ASSERT_EQ (num_cases_tested, 2 * 12 * (1+test_generated_data));
}
/* Verify that when presented with a consecutive pair of locations with
@@ -4017,7 +4046,7 @@ for_each_line_table_case (void (*testcase) (const line_table_case &))
static void
test_line_offset_overflow ()
{
- line_table_test ltt (line_table_case (5, 0));
+ line_table_test ltt (line_table_case (5, 0, false));
linemap_add (line_table, LC_ENTER, false, "foo.c", 0);
linemap_line_start (line_table, 1, 100);
@@ -4257,9 +4286,9 @@ input_cc_tests ()
test_should_have_column_data_p ();
test_unknown_location ();
test_builtins ();
- for_each_line_table_case (test_make_location_nonpure_range_endpoints);
+ for_each_line_table_case (test_make_location_nonpure_range_endpoints, true);
- for_each_line_table_case (test_accessing_ordinary_linemaps);
+ for_each_line_table_case (test_accessing_ordinary_linemaps, true);
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);
diff --git a/gcc/selftest.cc b/gcc/selftest.cc
index 20c10bbd055..7126b9901dd 100644
--- a/gcc/selftest.cc
+++ b/gcc/selftest.cc
@@ -163,14 +163,21 @@ assert_str_startswith (const location &loc,
named_temp_file::named_temp_file (const char *suffix)
{
- m_filename = make_temp_file (suffix);
- ASSERT_NE (m_filename, NULL);
+ if (suffix)
+ {
+ m_filename = make_temp_file (suffix);
+ ASSERT_NE (m_filename, NULL);
+ }
+ else
+ m_filename = nullptr;
}
/* Destructor. Delete the tempfile. */
named_temp_file::~named_temp_file ()
{
+ if (!m_filename)
+ return;
unlink (m_filename);
diagnostics_file_cache_forcibly_evict_file (m_filename);
free (m_filename);
@@ -183,7 +190,9 @@ named_temp_file::~named_temp_file ()
temp_source_file::temp_source_file (const location &loc,
const char *suffix,
const char *content)
-: named_temp_file (suffix)
+: named_temp_file (suffix),
+ content_buf (nullptr),
+ content_len (0)
{
FILE *out = fopen (get_filename (), "w");
if (!out)
@@ -192,19 +201,41 @@ temp_source_file::temp_source_file (const location &loc,
fclose (out);
}
-/* As above, but with a size, to allow for NUL bytes in CONTENT. */
+/* As above, but with a size, to allow for NUL bytes in CONTENT. When
+ IS_GENERATED==true, the data is kept in memory instead, for testing LC_GEN
+ maps. */
temp_source_file::temp_source_file (const location &loc,
const char *suffix,
const char *content,
- size_t sz)
-: named_temp_file (suffix)
+ size_t sz,
+ bool is_generated)
+: named_temp_file (is_generated ? nullptr : suffix),
+ content_buf (is_generated ? XNEWVEC (char, sz) : nullptr),
+ content_len (is_generated ? sz : 0)
{
- FILE *out = fopen (get_filename (), "w");
- if (!out)
- fail_formatted (loc, "unable to open tempfile: %s", get_filename ());
- fwrite (content, sz, 1, out);
- fclose (out);
+ if (is_generated)
+ {
+ gcc_assert (sz); /* Empty generated content is not supported. */
+ memcpy (content_buf, content, sz);
+ }
+ else
+ {
+ FILE *out = fopen (get_filename (), "w");
+ if (!out)
+ fail_formatted (loc, "unable to open tempfile: %s", get_filename ());
+ fwrite (content, sz, 1, out);
+ fclose (out);
+ }
+}
+
+temp_source_file::~temp_source_file ()
+{
+ if (content_buf)
+ {
+ diagnostics_file_cache_forcibly_evict_data (content_buf, content_len);
+ XDELETEVEC (content_buf);
+ }
}
/* Avoid introducing locale-specific differences in the results
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 20d522afda4..ede3b008145 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -25,6 +25,8 @@ along with GCC; see the file COPYING3. If not see
#if CHECKING_P
+struct line_map_ordinary;
+
namespace selftest {
/* A struct describing the source-location of a selftest, to make it
@@ -96,7 +98,7 @@ extern void assert_str_startswith (const location &loc,
class named_temp_file
{
public:
- named_temp_file (const char *suffix);
+ explicit named_temp_file (const char *suffix);
~named_temp_file ();
const char *get_filename () const { return m_filename; }
@@ -113,7 +115,13 @@ class temp_source_file : public named_temp_file
temp_source_file (const location &loc, const char *suffix,
const char *content);
temp_source_file (const location &loc, const char *suffix,
- const char *content, size_t sz);
+ const char *content, size_t sz,
+ bool is_generated = false);
+ ~temp_source_file ();
+
+ char *const content_buf;
+ const size_t content_len;
+ const line_map_ordinary *do_linemap_add (int line); /* In input.cc */
};
/* RAII-style class for avoiding introducing locale-specific differences
@@ -171,6 +179,10 @@ class line_table_test
/* Destructor. Restore the saved line_table. */
~line_table_test ();
+
+ /* When this is enabled in the line_table_case, test storing all the data
+ in memory rather than a file. */
+ bool m_generated_data;
};
/* Helper function for selftests that need a function decl. */
@@ -183,7 +195,8 @@ extern tree make_fndecl (tree return_type,
/* 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 &));
+for_each_line_table_case (void (*testcase) (const line_table_case &),
+ bool test_generated_data = false);
/* Read the contents of PATH into memory, returning a 0-terminated buffer
that must be freed by the caller.
next prev parent reply other threads:[~2023-08-09 22:14 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-21 23:08 [PATCH v3 0/4] diagnostics: libcpp: Overhaul locations for _Pragma tokens Lewis Hyatt
2023-07-21 23:08 ` [PATCH v3 1/4] diagnostics: libcpp: Add LC_GEN linemaps to support in-memory buffers Lewis Hyatt
2023-07-28 22:58 ` David Malcolm
2023-07-31 22:39 ` Lewis Hyatt
2023-08-09 22:14 ` [PATCH v4 0/8] diagnostics: libcpp: Overhaul locations for _Pragma tokens Lewis Hyatt
2023-08-09 22:14 ` [PATCH v4 1/8] libcpp: Add LC_GEN linemaps to support in-memory buffers Lewis Hyatt
2023-08-11 22:45 ` David Malcolm
2023-08-13 20:18 ` Lewis Hyatt
2023-08-09 22:14 ` [PATCH v4 2/8] libcpp: diagnostics: Support generated data in expanded locations Lewis Hyatt
2023-08-11 23:02 ` David Malcolm
2023-08-14 21:41 ` Lewis Hyatt
2023-08-09 22:14 ` [PATCH v4 3/8] diagnostics: Refactor class file_cache_slot Lewis Hyatt
2023-08-15 15:43 ` David Malcolm
2023-08-15 17:58 ` Lewis Hyatt
2023-08-15 19:39 ` David Malcolm
2023-08-23 21:22 ` Lewis Hyatt
2023-08-09 22:14 ` [PATCH v4 4/8] diagnostics: Support obtaining source code lines from generated data buffers Lewis Hyatt
2023-08-15 16:15 ` David Malcolm
2023-08-15 18:15 ` Lewis Hyatt
2023-08-15 19:46 ` David Malcolm
2023-08-15 20:08 ` Lewis Hyatt
2023-08-23 19:41 ` Lewis Hyatt
2023-08-09 22:14 ` Lewis Hyatt [this message]
2023-08-15 16:27 ` [PATCH v4 5/8] diagnostics: Support testing generated data in input.cc selftests David Malcolm
2023-08-09 22:14 ` [PATCH v4 6/8] diagnostics: Full support for generated data locations Lewis Hyatt
2023-08-15 16:39 ` David Malcolm
2023-08-09 22:14 ` [PATCH v4 7/8] diagnostics: libcpp: Assign real locations to the tokens inside _Pragma strings Lewis Hyatt
2023-08-09 22:14 ` [PATCH v4 8/8] diagnostics: Support generated data locations in SARIF output Lewis Hyatt
2023-08-15 17:04 ` David Malcolm
2023-08-15 17:51 ` Lewis Hyatt
2023-07-21 23:08 ` [PATCH v3 2/4] diagnostics: Handle generated data locations in edit_context Lewis Hyatt
2023-07-21 23:08 ` [PATCH v3 3/4] diagnostics: libcpp: Assign real locations to the tokens inside _Pragma strings Lewis Hyatt
2023-07-21 23:08 ` [PATCH v3 4/4] diagnostics: Support generated data locations in SARIF output Lewis Hyatt
2023-07-28 22:22 ` [PATCH v3 0/4] diagnostics: libcpp: Overhaul locations for _Pragma tokens David Malcolm
2023-07-29 14:27 ` Lewis Hyatt
2023-07-29 16:03 ` David Malcolm
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230809221414.2849878-6-lhyatt@gmail.com \
--to=lhyatt@gmail.com \
--cc=dmalcolm@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).