From 305c763476e1828bd5432b42723cd0eacd5c9df9 Mon Sep 17 00:00:00 2001 From: Detlef Riekenberg Date: Mon, 5 Feb 2024 00:01:39 +0100 Subject: [PATCH] yarpgen_v1: Add an option to change code output to help preparing a reduced testcase. This patch adds a new option "--reduce" ("-r") and changes the code output to print (and reset) the hash for every entry in all checksum functions. * Redirecting the output of the compiled program to a result file is needed. * Using a "diff -u" on the result files and finding/removing the working testcode is an easy way to get a reduced testcase. Example: https://savannah.nongnu.org/bugs/?63895 -- Regards ... Detlef --- src/main.cpp | 4 ++++ src/options.cpp | 3 ++- src/options.h | 1 + src/program.cpp | 12 ++++++++++-- src/sym_table.cpp | 20 ++++++++++++++++++++ 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 229c599e..d3626a03 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,6 +74,7 @@ void print_usage_and_exit (std::string error_msg = "") { std::cout << "\t-d, --out-dir= Output directory\n"; std::cout << "\t-s, --seed= Predefined seed (it is accepted in form of SSS or VV_SSS)\n"; std::cout << "\t-m, --bit-mode=<32/64> Generated test's bit mode\n"; + std::cout << "\t-r, --reduce Generate test with verbose output to help reduce a failed testcase\n"; std::cout << "\t--std= Generated test's language standard\n"; auto search_for_default_std = [] (const std::pair &pair) { return pair.second == options->standard_id; @@ -197,6 +198,9 @@ int main (int argc, char* argv[128]) { else if (!strcmp(argv[i], "-q")) { quiet = true; } + else if (!strcmp(argv[i], "-r") || !strcmp(argv[i], "--reduce")) { + options->reduce = true; + } else if (parse_long_args(i, argv, "--std", standard_action, "Can't recognize language standard:")) {} else if (parse_long_and_short_args(argc, i, argv, "-d", "--out-dir", out_dir_action, diff --git a/src/options.cpp b/src/options.cpp index 148d4f76..ab75d9d8 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -25,7 +25,8 @@ using namespace yarpgen; Options* yarpgen::options; Options::Options() : standard_id(CXX11), mode_64bit(true), windows_mode(false), - include_valarray(false), include_vector(false), include_array(false) { + include_valarray(false), include_vector(false), include_array(false), + reduce(false) { plane_yarpgen_version = yarpgen_version; plane_yarpgen_version.erase(std::remove(plane_yarpgen_version.begin(), plane_yarpgen_version.end(), '.'), plane_yarpgen_version.end()); diff --git a/src/options.h b/src/options.h index 1731e50b..70a031b6 100644 --- a/src/options.h +++ b/src/options.h @@ -53,6 +53,7 @@ struct Options { bool include_valarray; bool include_vector; bool include_array; + bool reduce; }; extern Options *options; diff --git a/src/program.cpp b/src/program.cpp index 42878d4d..d0e89baa 100644 --- a/src/program.cpp +++ b/src/program.cpp @@ -395,9 +395,17 @@ void Program::emit_main () { tf_prefix = NameHandler::common_test_func_prefix + std::to_string(i) + "_"; out_file << " " << tf_prefix << "init ();\n"; out_file << " " << tf_prefix << "foo ();\n"; - out_file << " " << tf_prefix << "checksum ();\n\n"; + out_file << " " << tf_prefix << "checksum ();\n"; + if (options->reduce) { + out_file << " printf(\"%d:%llu\\n\", __LINE__, seed);\n"; + if (i < gen_policy.get_test_func_count()) { + out_file << " seed=0;\n\n"; + } + } + } + if (!options->reduce) { + out_file << "\n printf(\"%llu\\n\", seed);\n"; } - out_file << " printf(\"%llu\\n\", seed);\n"; out_file << " return 0;\n"; out_file << "}\n"; diff --git a/src/sym_table.cpp b/src/sym_table.cpp index 9f0ae846..ebe1e22f 100644 --- a/src/sym_table.cpp +++ b/src/sym_table.cpp @@ -201,6 +201,10 @@ void SymbolTable::emit_variable_def (std::ostream& stream, std::string offset) { void SymbolTable::emit_variable_check (std::ostream& stream, std::string offset) { for (const auto &i : variable) { stream << offset + "hash(&seed, " + i->get_name() + ");\n"; + if (options->reduce) { + stream << offset + "printf(\"" + i->get_name() + ":%llu\\n\", seed);\n"; + stream << offset + "seed=0;\n"; + } } } @@ -300,6 +304,12 @@ void SymbolTable::emit_single_struct_check (std::shared_ptr parent_m stream << offset + "hash(&seed, "; member_expr->emit(stream); stream << ");\n"; + if (options->reduce) { + stream << offset + "printf(\""; + member_expr->emit(stream); + stream << ":%llu\\n\", seed);\n"; + stream << offset + "seed=0;\n"; + } } } } @@ -357,6 +367,10 @@ void SymbolTable::emit_array_check (std::ostream& stream, std::string offset) { switch (array_elem->get_class_id()) { case Data::VAR: stream << offset + "hash(&seed, " + array_elem->get_name() + ");\n"; + if (options->reduce) { + stream << offset + "printf(\"" + array_elem->get_name() + ":%llu\\n\", seed);\n"; + stream << offset + "seed=0;\n"; + } break; case Data::STRUCT: emit_single_struct_check(nullptr, std::static_pointer_cast(array_elem), stream, offset); @@ -392,6 +406,12 @@ void SymbolTable::emit_ptr_check (std::ostream& stream, std::string offset) { stream << offset + "hash(&seed, "; pointers.deref_expr.at(i)->emit(stream); stream << ");\n"; + if (options->reduce) { + stream << offset + "printf(\""; + pointers.deref_expr.at(i)->emit(stream); + stream << ":%llu\\n\", seed);\n"; + stream << offset + "seed=0;\n"; + } } }