diff --git a/src/ArrayVariable.h b/src/ArrayVariable.h index eed9fe7d6..1f60067f5 100644 --- a/src/ArrayVariable.h +++ b/src/ArrayVariable.h @@ -80,6 +80,7 @@ class ArrayVariable : public Variable void output_init(std::ostream &out, const Expression* init, const vector& cvs, int indent) const; void output_addr_checks(std::ostream &out, const Variable* var, string field_name, int indent) const; void add_init_value(const Expression* e) { init_values.push_back(e);} + const vector& get_init_values(void) const { return init_values;} string build_initializer_str(const vector& init_strings) const; string build_init_recursive(size_t dimen, const vector& init_strings) const; diff --git a/src/Reducer.cpp b/src/Reducer.cpp index e2a3434d0..ece7f6bff 100644 --- a/src/Reducer.cpp +++ b/src/Reducer.cpp @@ -71,8 +71,6 @@ Reducer::Reducer(string fname) rewrite_calls_inside(NULL), reduce_binaries(false), output_if_ids(false), - print_value_with_multi_lines(false), - test_command_line_option(false), monitored_var(NULL), monitored_func(NULL), monitored_call_id(""), @@ -128,6 +126,22 @@ Reducer::configure(void) monitored_var = key; used_vars.push_back(key->get_named_var()); } + // find the line that crashed a compiler + else if (line.find("crc lines") == 0) { + getline(conf, line); + StringUtils::chop(line); + // find the global variables in CRC statements, and mark them as used + vector strs; + StringUtils::split_string(line, strs, "(),[."); + for (size_t i=0; i blks; s->get_blocks(blks); bool must_dump = false; for (j=0; j& vars) void Reducer::expand_used_vars(void) { - size_t i; + size_t i, j; for (i=0; iinit; - if (init && init->term_type == eVariable) { - const ExpressionVariable* ev = (const ExpressionVariable*)(init); - if (ev->get_indirect_level() < 0) { - string dummy; - const Variable* addr_var = ev->get_var()->get_array(dummy); - // if not an array ... - if (addr_var == 0) { - addr_var = ev->get_var(); - } - addr_var = addr_var->get_named_var(); - if (!is_var_used(addr_var)) { - bool found = false; - // if find no appropriate variable in used list, use the original variable - if (!found) { - used_vars.push_back(addr_var); + vector init_values; + if (v->isArray) { + const ArrayVariable* av = dynamic_cast(v); + init_values = av->get_init_values(); + } + init_values.push_back(v->init); + + for (j=0; jterm_type == eVariable) { + const ExpressionVariable* ev = (const ExpressionVariable*)(init); + if (ev->get_indirect_level() < 0) { + string dummy; + const Variable* addr_var = ev->get_var()->get_array(dummy); + // if not an array ... + if (addr_var == 0) { + addr_var = ev->get_var(); } - } + // if addr_var is a field, get the container var + addr_var = addr_var->get_named_var(); + if (!is_var_used(addr_var)) { + used_vars.push_back(addr_var); + } + } } } } diff --git a/src/Reducer.h b/src/Reducer.h index 11028a9ed..963cf275d 100644 --- a/src/Reducer.h +++ b/src/Reducer.h @@ -122,11 +122,10 @@ class Reducer const Function* rewrite_calls_inside; bool reduce_binaries; bool output_if_ids; - bool print_value_with_multi_lines; - bool test_command_line_option; const Variable* monitored_var; const Function* monitored_func; string monitored_call_id; + string crc_lines; std::map map_active_blks; vector all_blks; diff --git a/src/ReducerOutputMgr.cpp b/src/ReducerOutputMgr.cpp index 25fd9c787..cc94f5a27 100644 --- a/src/ReducerOutputMgr.cpp +++ b/src/ReducerOutputMgr.cpp @@ -245,20 +245,25 @@ ReducerOutputMgr::output_main_func(std::ostream& out) { size_t i; const Function* f = reducer->main; - if (!reducer->test_command_line_option && f->param.size() == 0 && (reducer->main_str == "" || reducer->main_str.find("func_")==0)) { + if (f->param.size() == 0 && (reducer->main_str == "" || reducer->main_str.find("func_")==0)) { out << "int main(void)" << endl; - output_block(f->body, out, 0); + if (reducer->is_blk_deleted(f->body)) { + out << "{" << endl; + if (!reducer->crc_lines.empty()) { + output_tab(out, 1); + out << reducer->crc_lines << endl; + } + output_tab(out, 1); + out << "return 0;" << endl; + out << "}" << endl; + } + else { + output_block(f->body, out, 0); + } } else { output_func(f, out); - // make an artificial main function - if (reducer->test_command_line_option) { - out << endl << "int main(int argc, char* argv[]) {" << endl; - output_tab(out, 1); - out << "if (argc == 2 && strcmp(argv[1], \"1\") == 0) { int i = 1;}" << endl; - } else { - out << endl << "int main(void) {" << endl; - } + out << endl << "int main(void) {" << endl; output_tab(out, 1); // break up function call and parameters, and skip parameters that are reduced vector strs; @@ -620,11 +625,16 @@ ReducerOutputMgr::output_reduced_stm(const Statement* stm, std::ostream &out, in ostringstream oss; const Variable* key = reducer->monitored_var; oss << "checksum " << key->get_actual_name() << " = "; - key->output_runtime_value(out, oss.str(), "\\n", indent, reducer->print_value_with_multi_lines); + key->output_runtime_value(out, oss.str(), "\\n", indent, 0); outputln(out); } } if (stm->func == GetFirstFunction()) { + // output crc lines if they are required + if (!reducer->crc_lines.empty()) { + output_tab(out, indent); + out << reducer->crc_lines; + } output_tab(out, indent); out << "return 0;" << endl; return;