8sa1-gcc/gcc/selftest.c
Jakub Jelinek 700d4cb08c Fix up duplicated duplicated words mostly in comments
In the r10-7197-gbae7b38cf8a21e068ad5c0bab089dedb78af3346 commit I've
noticed duplicated word in a message, which lead me to grep for those and
we have a tons of them.
I've used
grep -v 'long long\|optab optab\|template template\|double double' *.[chS] */*.[chS] *.def config/*/* 2>/dev/null | grep ' \([a-zA-Z]\+\) \1 '
Note, the command will not detect the doubled words at the start or end of
line or when one of the words is at the end of line and the next one at the
start of another one.
Some of it is fairly obvious, e.g. all the "the the" cases which is
something I've posted and committed patch for already e.g. in 2016,
other cases are often valid, e.g. "that that" seems to look mostly ok to me.
Some cases are quite hard to figure out, I've left out some of them from the
patch (e.g. "and and" in some cases isn't talking about bitwise/logical and
and so looks incorrect, but in other cases it is talking about those
operations).
In most cases the right solution seems to be to remove one of the duplicated
words, but not always.

I think most important are the ones with user visible messages (in the patch
3 of the first 4 hunks), the rest is just comments (and internal
documentation; for that see the doc/tm.texi changes).

2020-03-17  Jakub Jelinek  <jakub@redhat.com>

	* lra-spills.c (remove_pseudos): Fix up duplicated word issue in
	a dump message.
	* tree-sra.c (create_access_replacement): Fix up duplicated word issue
	in a comment.
	* read-rtl-function.c (find_param_by_name,
	function_reader::parse_enum_value, function_reader::get_insn_by_uid):
	Likewise.
	* spellcheck.c (get_edit_distance_cutoff): Likewise.
	* tree-data-ref.c (create_ifn_alias_checks): Likewise.
	* tree.def (SWITCH_EXPR): Likewise.
	* selftest.c (assert_str_contains): Likewise.
	* ipa-param-manipulation.h (class ipa_param_body_adjustments):
	Likewise.
	* tree-ssa-math-opts.c (convert_expand_mult_copysign): Likewise.
	* tree-ssa-loop-split.c (find_vdef_in_loop): Likewise.
	* langhooks.h (struct lang_hooks_for_decls): Likewise.
	* ipa-prop.h (struct ipa_param_descriptor): Likewise.
	* tree-ssa-strlen.c (handle_builtin_string_cmp, handle_store):
	Likewise.
	* tree-ssa-dom.c (simplify_stmt_for_jump_threading): Likewise.
	* tree-ssa-reassoc.c (reassociate_bb): Likewise.
	* tree.c (component_ref_size): Likewise.
	* hsa-common.c (hsa_init_compilation_unit_data): Likewise.
	* gimple-ssa-sprintf.c (get_string_length, format_string,
	format_directive): Likewise.
	* omp-grid.c (grid_process_kernel_body_copy): Likewise.
	* input.c (string_concat_db::get_string_concatenation,
	test_lexer_string_locations_ucn4): Likewise.
	* cfgexpand.c (pass_expand::execute): Likewise.
	* gimple-ssa-warn-restrict.c (builtin_memref::offset_out_of_bounds,
	maybe_diag_overlap): Likewise.
	* rtl.c (RTX_CODE_HWINT_P_1): Likewise.
	* shrink-wrap.c (spread_components): Likewise.
	* tree-ssa-dse.c (initialize_ao_ref_for_dse, valid_ao_ref_for_dse):
	Likewise.
	* tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds):
	Likewise.
	* dwarf2out.c (dwarf2out_early_finish): Likewise.
	* gimple-ssa-store-merging.c: Likewise.
	* ira-costs.c (record_operand_costs): Likewise.
	* tree-vect-loop.c (vectorizable_reduction): Likewise.
	* target.def (dispatch): Likewise.
	(validate_dims, gen_ccmp_first): Fix up duplicated word issue
	in documentation text.
	* doc/tm.texi: Regenerated.
	* config/i386/x86-tune.def (X86_TUNE_PARTIAL_FLAG_REG_STALL): Fix up
	duplicated word issue in a comment.
	* config/i386/i386.c (ix86_test_loading_unspec): Likewise.
	* config/i386/i386-features.c (remove_partial_avx_dependency):
	Likewise.
	* config/msp430/msp430.c (msp430_select_section): Likewise.
	* config/gcn/gcn-run.c (load_image): Likewise.
	* config/aarch64/aarch64-sve.md (sve_ld1r<mode>): Likewise.
	* config/aarch64/aarch64.c (aarch64_gen_adjusted_ldpstp): Likewise.
	* config/aarch64/falkor-tag-collision-avoidance.c
	(single_dest_per_chain): Likewise.
	* config/nvptx/nvptx.c (nvptx_record_fndecl): Likewise.
	* config/fr30/fr30.c (fr30_arg_partial_bytes): Likewise.
	* config/rs6000/rs6000-string.c (expand_cmp_vec_sequence): Likewise.
	* config/rs6000/rs6000-p8swap.c (replace_swapped_load_constant):
	Likewise.
	* config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Likewise.
	* config/rs6000/rs6000.c (rs6000_option_override_internal): Likewise.
	* config/rs6000/rs6000-logue.c
	(rs6000_emit_probe_stack_range_stack_clash): Likewise.
	* config/nds32/nds32-md-auxiliary.c (nds32_split_ashiftdi3): Likewise.
	Fix various other issues in the comment.
c-family/
	* c-common.c (resolve_overloaded_builtin): Fix up duplicated word
	issue in a diagnostic message.
cp/
	* pt.c (tsubst): Fix up duplicated word issue in a diagnostic message.
	(lookup_template_class_1, tsubst_expr): Fix up duplicated word issue
	in a comment.
	* parser.c (cp_parser_statement, cp_parser_linkage_specification,
	cp_parser_placeholder_type_specifier,
	cp_parser_constraint_requires_parens): Likewise.
	* name-lookup.c (suggest_alternative_in_explicit_scope): Likewise.
fortran/
	* array.c (gfc_check_iter_variable): Fix up duplicated word issue
	in a comment.
	* arith.c (gfc_arith_concat): Likewise.
	* resolve.c (gfc_resolve_ref): Likewise.
	* frontend-passes.c (matmul_lhs_realloc): Likewise.
	* module.c (gfc_match_submodule, load_needed): Likewise.
	* trans-expr.c (gfc_init_se): Likewise.
2020-03-17 13:52:19 +01:00

413 lines
11 KiB
C

/* A self-testing framework, for use by -fself-test.
Copyright (C) 2015-2020 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "selftest.h"
#include "intl.h"
#if CHECKING_P
namespace selftest {
int num_passes;
/* Record the successful outcome of some aspect of a test. */
void
pass (const location &/*loc*/, const char */*msg*/)
{
num_passes++;
}
/* Report the failed outcome of some aspect of a test and abort. */
void
fail (const location &loc, const char *msg)
{
fprintf (stderr,"%s:%i: %s: FAIL: %s\n", loc.m_file, loc.m_line,
loc.m_function, msg);
abort ();
}
/* As "fail", but using printf-style formatted output. */
void
fail_formatted (const location &loc, const char *fmt, ...)
{
va_list ap;
fprintf (stderr, "%s:%i: %s: FAIL: ", loc.m_file, loc.m_line,
loc.m_function);
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
va_end (ap);
fprintf (stderr, "\n");
abort ();
}
/* Implementation detail of ASSERT_STREQ.
Compare val1 and val2 with strcmp. They ought
to be non-NULL; fail gracefully if either or both are NULL. */
void
assert_streq (const location &loc,
const char *desc_val1, const char *desc_val2,
const char *val1, const char *val2)
{
/* If val1 or val2 are NULL, fail with a custom error message. */
if (val1 == NULL)
if (val2 == NULL)
fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=NULL val2=NULL",
desc_val1, desc_val2);
else
fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=NULL val2=\"%s\"",
desc_val1, desc_val2, val2);
else
if (val2 == NULL)
fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=\"%s\" val2=NULL",
desc_val1, desc_val2, val1);
else
{
if (strcmp (val1, val2) == 0)
pass (loc, "ASSERT_STREQ");
else
fail_formatted (loc, "ASSERT_STREQ (%s, %s) val1=\"%s\" val2=\"%s\"",
desc_val1, desc_val2, val1, val2);
}
}
/* Implementation detail of ASSERT_STR_CONTAINS.
Use strstr to determine if val_needle is within val_haystack.
::selftest::pass if it is found.
::selftest::fail if it is not found. */
void
assert_str_contains (const location &loc,
const char *desc_haystack,
const char *desc_needle,
const char *val_haystack,
const char *val_needle)
{
/* If val_haystack is NULL, fail with a custom error message. */
if (val_haystack == NULL)
fail_formatted (loc, "ASSERT_STR_CONTAINS (%s, %s) haystack=NULL",
desc_haystack, desc_needle);
/* If val_needle is NULL, fail with a custom error message. */
if (val_needle == NULL)
fail_formatted (loc,
"ASSERT_STR_CONTAINS (%s, %s) haystack=\"%s\" needle=NULL",
desc_haystack, desc_needle, val_haystack);
const char *test = strstr (val_haystack, val_needle);
if (test)
pass (loc, "ASSERT_STR_CONTAINS");
else
fail_formatted
(loc, "ASSERT_STR_CONTAINS (%s, %s) haystack=\"%s\" needle=\"%s\"",
desc_haystack, desc_needle, val_haystack, val_needle);
}
/* Implementation detail of ASSERT_STR_STARTSWITH.
Determine if VAL_STR starts with VAL_PREFIX.
::selftest::pass if VAL_STR does start with VAL_PREFIX.
::selftest::fail if it does not, or either is NULL (using
DESC_STR and DESC_PREFIX in the error message). */
void
assert_str_startswith (const location &loc,
const char *desc_str,
const char *desc_prefix,
const char *val_str,
const char *val_prefix)
{
/* If val_str is NULL, fail with a custom error message. */
if (val_str == NULL)
fail_formatted (loc, "ASSERT_STR_STARTSWITH (%s, %s) str=NULL",
desc_str, desc_prefix);
/* If val_prefix is NULL, fail with a custom error message. */
if (val_prefix == NULL)
fail_formatted (loc,
"ASSERT_STR_STARTSWITH (%s, %s) str=\"%s\" prefix=NULL",
desc_str, desc_prefix, val_str);
const char *test = strstr (val_str, val_prefix);
if (test == val_str)
pass (loc, "ASSERT_STR_STARTSWITH");
else
fail_formatted
(loc, "ASSERT_STR_STARTSWITH (%s, %s) str=\"%s\" prefix=\"%s\"",
desc_str, desc_prefix, val_str, val_prefix);
}
/* Constructor. Generate a name for the file. */
named_temp_file::named_temp_file (const char *suffix)
{
m_filename = make_temp_file (suffix);
ASSERT_NE (m_filename, NULL);
}
/* Destructor. Delete the tempfile. */
named_temp_file::~named_temp_file ()
{
unlink (m_filename);
diagnostics_file_cache_forcibly_evict_file (m_filename);
free (m_filename);
}
/* Constructor. Create a tempfile using SUFFIX, and write CONTENT to
it. Abort if anything goes wrong, using LOC as the effective
location in the problem report. */
temp_source_file::temp_source_file (const location &loc,
const char *suffix,
const char *content)
: named_temp_file (suffix)
{
FILE *out = fopen (get_filename (), "w");
if (!out)
fail_formatted (loc, "unable to open tempfile: %s", get_filename ());
fprintf (out, "%s", content);
fclose (out);
}
/* Avoid introducing locale-specific differences in the results
by hardcoding open_quote and close_quote. */
auto_fix_quotes::auto_fix_quotes ()
{
m_saved_open_quote = open_quote;
m_saved_close_quote = close_quote;
open_quote = "`";
close_quote = "'";
}
/* Restore old values of open_quote and close_quote. */
auto_fix_quotes::~auto_fix_quotes ()
{
open_quote = m_saved_open_quote;
close_quote = m_saved_close_quote;
}
/* Read the contents of PATH into memory, returning a 0-terminated buffer
that must be freed by the caller.
Fail (and abort) if there are any problems, with LOC as the reported
location of the failure. */
char *
read_file (const location &loc, const char *path)
{
FILE *f_in = fopen (path, "r");
if (!f_in)
fail_formatted (loc, "unable to open file: %s", path);
/* Read content, allocating FIXME. */
char *result = NULL;
size_t total_sz = 0;
size_t alloc_sz = 0;
char buf[4096];
size_t iter_sz_in;
while ( (iter_sz_in = fread (buf, 1, sizeof (buf), f_in)) )
{
gcc_assert (alloc_sz >= total_sz);
size_t old_total_sz = total_sz;
total_sz += iter_sz_in;
/* Allow 1 extra byte for 0-termination. */
if (alloc_sz < (total_sz + 1))
{
size_t new_alloc_sz = alloc_sz ? alloc_sz * 2: total_sz + 1;
result = (char *)xrealloc (result, new_alloc_sz);
alloc_sz = new_alloc_sz;
}
memcpy (result + old_total_sz, buf, iter_sz_in);
}
if (!feof (f_in))
fail_formatted (loc, "error reading from %s: %s", path,
xstrerror (errno));
fclose (f_in);
/* 0-terminate the buffer. */
gcc_assert (total_sz < alloc_sz);
result[total_sz] = '\0';
return result;
}
/* The path of SRCDIR/testsuite/selftests. */
const char *path_to_selftest_files = NULL;
/* Convert a path relative to SRCDIR/testsuite/selftests
to a real path (either absolute, or relative to pwd).
The result should be freed by the caller. */
char *
locate_file (const char *name)
{
ASSERT_NE (NULL, path_to_selftest_files);
return concat (path_to_selftest_files, "/", name, NULL);
}
/* selftest::test_runner's ctor. */
test_runner::test_runner (const char *name)
: m_name (name),
m_start_time (get_run_time ())
{
}
/* selftest::test_runner's dtor. Print a summary line to stderr. */
test_runner::~test_runner ()
{
/* Finished running tests. */
long finish_time = get_run_time ();
long elapsed_time = finish_time - m_start_time;
fprintf (stderr,
"%s: %i pass(es) in %ld.%06ld seconds\n",
m_name, num_passes,
elapsed_time / 1000000, elapsed_time % 1000000);
}
/* Selftests for libiberty. */
/* Verify that xstrndup generates EXPECTED when called on SRC and N. */
static void
assert_xstrndup_eq (const char *expected, const char *src, size_t n)
{
char *buf = xstrndup (src, n);
ASSERT_STREQ (expected, buf);
free (buf);
}
/* Verify that xstrndup works as expected. */
static void
test_xstrndup ()
{
assert_xstrndup_eq ("", "test", 0);
assert_xstrndup_eq ("t", "test", 1);
assert_xstrndup_eq ("te", "test", 2);
assert_xstrndup_eq ("tes", "test", 3);
assert_xstrndup_eq ("test", "test", 4);
assert_xstrndup_eq ("test", "test", 5);
/* Test on an string without zero termination. */
const char src[4] = {'t', 'e', 's', 't'};
assert_xstrndup_eq ("", src, 0);
assert_xstrndup_eq ("t", src, 1);
assert_xstrndup_eq ("te", src, 2);
assert_xstrndup_eq ("tes", src, 3);
assert_xstrndup_eq ("test", src, 4);
}
/* Run selftests for libiberty. */
static void
test_libiberty ()
{
test_xstrndup ();
}
/* Selftests for the selftest system itself. */
/* Sanity-check the ASSERT_ macros with various passing cases. */
static void
test_assertions ()
{
ASSERT_TRUE (true);
ASSERT_FALSE (false);
ASSERT_EQ (1, 1);
ASSERT_EQ_AT (SELFTEST_LOCATION, 1, 1);
ASSERT_NE (1, 2);
ASSERT_GT (2, 1);
ASSERT_GT_AT (SELFTEST_LOCATION, 2, 1);
ASSERT_LT (1, 2);
ASSERT_LT_AT (SELFTEST_LOCATION, 1, 2);
ASSERT_STREQ ("test", "test");
ASSERT_STREQ_AT (SELFTEST_LOCATION, "test", "test");
ASSERT_STR_CONTAINS ("foo bar baz", "bar");
}
/* Verify named_temp_file. */
static void
test_named_temp_file ()
{
named_temp_file t (".txt");
FILE *f = fopen (t.get_filename (), "w");
if (!f)
fail_formatted (SELFTEST_LOCATION,
"unable to open %s for writing", t.get_filename ());
fclose (f);
}
/* Verify read_file (and also temp_source_file). */
static void
test_read_file ()
{
temp_source_file t (SELFTEST_LOCATION, "test1.s",
"\tjmp\t.L2\n");
char *buf = read_file (SELFTEST_LOCATION, t.get_filename ());
ASSERT_STREQ ("\tjmp\t.L2\n", buf);
free (buf);
}
/* Verify locate_file (and read_file). */
static void
test_locate_file ()
{
char *path = locate_file ("example.txt");
char *buf = read_file (SELFTEST_LOCATION, path);
ASSERT_STREQ ("example of a selftest file\n", buf);
free (buf);
free (path);
}
/* Run all of the selftests within this file. */
void
selftest_c_tests ()
{
test_libiberty ();
test_assertions ();
test_named_temp_file ();
test_read_file ();
test_locate_file ();
}
} // namespace selftest
#endif /* #if CHECKING_P */