From patchwork Thu Aug 18 16:53:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 660483 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sFWdq2n3Rz9t0M for ; Fri, 19 Aug 2016 02:24:46 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=kCo24AsC; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=SsdGy8OjKpdt olPECucLyabZUCRF5iiSd//SX1MF3j/G3uaXo7EcnuYbHjDOZeywVlku8wLhWH/O nz4I5vORbwguAZmYnzfpmFo1mlXsxD5L3PNl0LpOmSl9t/E3i+lEnWF3K2oirXzS NpcB/zMaIJbanB2xIDtR2fDylJe/Z6c= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=+4fZ/ITx/jCBLm8q/H Fg8LUetQM=; b=kCo24AsC0lYQ0xWw3ohJhoMuVNeGTu26xfunAWWzeZqNRMo0zf Axm9NAQvZdZJ4iGBBSMh4Df3Ce11P6hu/bp9ppYstJXoJmpH9tZ83a8Q4qRkZUHA 0xE0fGEWWYNyzbxFhtX/nScl1NZt48e4jXvPcJFj6dGncT5w18POc3bCY= Received: (qmail 79673 invoked by alias); 18 Aug 2016 16:24:31 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 79581 invoked by uid 89); 18 Aug 2016 16:24:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=families, sk:UNKNOWN, sk:unknown, restoring X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 18 Aug 2016 16:24:18 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 79ADF80F7C for ; Thu, 18 Aug 2016 16:24:14 +0000 (UTC) Received: from c64.redhat.com (vpn-228-74.phx2.redhat.com [10.3.228.74]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u7IGODGb002280; Thu, 18 Aug 2016 12:24:13 -0400 From: David Malcolm To: gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [committed] selftest.h: add class line_table_test Date: Thu, 18 Aug 2016 12:53:07 -0400 Message-Id: <1471539187-56581-1-git-send-email-dmalcolm@redhat.com> X-IsSubscribed: yes 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. Successfully bootstrapped®rtested on x86_64-pc-linux-gnu. Committed to trunk as r239580. 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. --- gcc/input.c | 126 +++++++++++++++++++++++++++++++++------------------------ gcc/input.h | 1 + gcc/selftest.h | 42 +++++++++++++++++++ 3 files changed, 117 insertions(+), 52 deletions(-) diff --git a/gcc/input.c b/gcc/input.c index 76a3307..2dcecfb 100644 --- a/gcc/input.c +++ b/gcc/input.c @@ -114,6 +114,13 @@ location_t input_location = UNKNOWN_LOCATION; 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 const size_t fcache_tab_size = 16; 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, ASSERT_EQ (exp_colnum, LOCATION_COLUMN (loc)); } -/* Various selftests in this file involve constructing a line table - and one or more line maps within it. +/* Various selftests involve 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: @@ -1618,29 +1625,35 @@ struct line_table_case int m_base_location; }; -/* A class for overriding the global "line_table" within a selftest, - restoring its value afterwards. */ +/* Constructor. Store the old value of line_table, and create a new + one, using sane defaults. */ -class temp_line_table +line_table_test::line_table_test () { - public: - temp_line_table (const line_table_case &); - ~temp_line_table (); - - private: - line_maps *m_old_line_table; -}; + gcc_assert (saved_line_table == NULL); + saved_line_table = line_table; + line_table = ggc_alloc (); + linemap_init (line_table, BUILTINS_LOCATION); + gcc_assert (saved_line_table->reallocator); + 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 one, using the sitation described in CASE_. */ -temp_line_table::temp_line_table (const line_table_case &case_) - : m_old_line_table (line_table) +line_table_test::line_table_test (const line_table_case &case_) { + gcc_assert (saved_line_table == NULL); + saved_line_table = line_table; line_table = ggc_alloc (); linemap_init (line_table, BUILTINS_LOCATION); - line_table->reallocator = m_old_line_table->reallocator; - line_table->round_alloc_size = m_old_line_table->round_alloc_size; + gcc_assert (saved_line_table->reallocator); + 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; if (case_.m_base_location) { @@ -1651,9 +1664,11 @@ temp_line_table::temp_line_table (const line_table_case &case_) /* 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. */ @@ -1661,7 +1676,7 @@ temp_line_table::~temp_line_table () static void 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. */ linemap_add (line_table, LC_ENTER, false, "foo.c", 0); @@ -1813,7 +1828,7 @@ test_lexer (const line_table_case &case_) " 42\n"); 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); @@ -1876,7 +1891,7 @@ struct lexer_test const cpp_token *get_token (); temp_source_file m_tempfile; - temp_line_table m_tmp_lt; + line_table_test m_ltt; cpp_reader *m_parser; string_concat_db m_concats; }; @@ -1948,7 +1963,7 @@ lexer_test::lexer_test (const line_table_case &case_, const char *content, lexer_test_options *options) : /* Create a tempfile and write the text to it. */ m_tempfile (SELFTEST_LOCATION, ".c", content), - m_tmp_lt (case_), + m_ltt (case_), m_parser (cpp_create_reader (CLK_GNUC99, NULL, line_table)), m_concats () { @@ -3129,15 +3144,11 @@ static const location_t boundary_locations[] = { 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 -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, we want to explore a test matrix of interesting line_table situations, running various selftests for each case within the @@ -3158,30 +3169,7 @@ input_c_tests () { line_table_case c (default_range_bits, boundary_locations[loc_idx]); - /* Run all tests for the given case within the test matrix. */ - 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); + testcase (c); num_cases_tested++; } @@ -3189,6 +3177,40 @@ input_c_tests () /* Verify that we fully covered the test matrix. */ 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 (); } diff --git a/gcc/input.h b/gcc/input.h index 0f187c7..c99abfd 100644 --- a/gcc/input.h +++ b/gcc/input.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "line-map.h" 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. */ #define UNKNOWN_LOCATION ((source_location) 0) diff --git a/gcc/selftest.h b/gcc/selftest.h index 72de61f..58a40f6 100644 --- a/gcc/selftest.h +++ b/gcc/selftest.h @@ -85,6 +85,48 @@ class temp_source_file 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 alphabetical order. */ extern void bitmap_c_tests ();