From bd0598ee0545f2a665d45a4b430f6b0f421f4603 Mon Sep 17 00:00:00 2001 From: shubhamnarlawar77 Date: Thu, 20 Dec 2018 15:33:05 +0530 Subject: [PATCH] Added support for computed goto extension --- src/Block.cpp | 47 ++++++++++++++++++++++++++++++++- src/Block.h | 3 +++ src/CGOptions.cpp | 2 ++ src/CGOptions.h | 3 +++ src/DefaultProgramGenerator.cpp | 1 - src/RandomProgramGenerator.cpp | 13 +++++++++ src/StatementGoto.cpp | 27 ++++++++++++++++++- src/StatementGoto.h | 3 +++ 8 files changed, 96 insertions(+), 3 deletions(-) diff --git a/src/Block.cpp b/src/Block.cpp index 798f2765b..540fd4cf4 100644 --- a/src/Block.cpp +++ b/src/Block.cpp @@ -65,6 +65,8 @@ #include "Expression.h" #include "VectorFilter.h" +#include +#include using namespace std; /////////////////////////////////////////////////////////////////////////////// @@ -188,7 +190,7 @@ Block::make_random(CGContext &cg_context, bool looping) curr_func->stack.pop_back(); if (Error::get_error() != SUCCESS) { - //curr_func->stack.pop_back(); + curr_func->stack.pop_back(); delete b; return NULL; } @@ -196,6 +198,32 @@ Block::make_random(CGContext &cg_context, bool looping) // ISSUE: in the exhaustive mode, do we need a return statement here // if the last statement is not? Error::set_error(SUCCESS); + + + if(CGOptions::computed_goto()){ + if(curr_func->blocks[0]->stm_id==b->stm_id){ + std::vector labels; + labels.clear(); + curr_func->blocks[0]->find_contained_labels(labels); + string ss=""; + for (std::vector::iterator itr=labels.begin();itr!=labels.end();itr++) { + ss.clear(); + ss += "&&"; + ss += *itr; + curr_func->blocks[0]->addr_labels.push_back(ss);//only adds in the main array related to function. + } + //__________________________________________________________ + for (size_t i=0; icfg_edges.size();i++) { + const CFGEdge* e = fm->cfg_edges[i]; + if(e->src->eType == eGoto) { + const StatementGoto* sg = dynamic_cast(e->src); + assert(sg); + sg->change_label(curr_func->blocks[0]->addr_labels); + } + } + + } + } return b; } @@ -295,6 +323,10 @@ Block::Output(std::ostream &out, FactMgr* fm, int indent) const ss << "block id: " << stm_id; output_comment_line(out, ss.str()); + if(CGOptions::computed_goto()){ + if(!this->addr_labels.empty()) + this->print_label_addr_array(out,indent); + } if (CGOptions::depth_protect()) { out << "DEPTH++;" << endl; } @@ -805,6 +837,19 @@ Block::post_creation_analysis(CGContext& cg_context, const Effect& pre_effect) } } +void +Block::print_label_addr_array(std::ostream &out , int indent) const{ + ostringstream ss; + output_tab (out,indent); + cout << "/*\nNUMBER OF GOTO'S IN ABOVEE BLOCK:" << addr_labels.size() << "*\/"; + cout << "\nvoid *target[] = { "; + for(unsigned int i=0; i < addr_labels.size();i++){ + i!=0 ? cout << ", " : cout << ""; + cout << addr_labels[i]; + } + + cout << "};\n"; +} /////////////////////////////////////////////////////////////////////////////// // Local Variables: diff --git a/src/Block.h b/src/Block.h index bb87af540..6bcdc3ecb 100644 --- a/src/Block.h +++ b/src/Block.h @@ -80,6 +80,9 @@ class Block : public Statement Block* random_parent_block(void); int block_size() { return block_size_; } + std::vector addr_labels; + void print_label_addr_array(std::ostream&, int) const; + // These are currently accessed directly. std::vector stms; std::vector deleted_stms; diff --git a/src/CGOptions.cpp b/src/CGOptions.cpp index 6c9d3dcad..84b5d9a7d 100644 --- a/src/CGOptions.cpp +++ b/src/CGOptions.cpp @@ -199,6 +199,7 @@ DEFINE_GETTER_SETTER_BOOL(const_struct_union_fields); DEFINE_GETTER_SETTER_BOOL(lang_cpp); DEFINE_GETTER_SETTER_BOOL(cpp11); DEFINE_GETTER_SETTER_BOOL(fast_execution); +DEFINE_GETTER_SETTER_BOOL(computed_goto); void CGOptions::set_default_builtin_kinds() @@ -313,6 +314,7 @@ CGOptions::set_default_settings(void) fast_execution(false); set_default_builtin_kinds(); + computed_goto(false); } // Add options necessary for cpp diff --git a/src/CGOptions.h b/src/CGOptions.h index ee7bb5ee4..cdd4b960a 100644 --- a/src/CGOptions.h +++ b/src/CGOptions.h @@ -363,6 +363,8 @@ class CGOptions { static bool signed_char_index(void); static bool signed_char_index(bool p); + static bool computed_goto(void); + static bool computed_goto(bool p); ///////////////////////////////////////////////////////// static void set_default_settings(void); @@ -579,6 +581,7 @@ class CGOptions { static bool no_return_dead_ptr_; static bool hash_value_printf_; static bool signed_char_index_; + static bool computed_goto_; static std::string dump_default_probabilities_; static std::string dump_random_probabilities_; static std::string probability_configuration_; diff --git a/src/DefaultProgramGenerator.cpp b/src/DefaultProgramGenerator.cpp index f355e9c08..2402e05b6 100644 --- a/src/DefaultProgramGenerator.cpp +++ b/src/DefaultProgramGenerator.cpp @@ -91,7 +91,6 @@ void DefaultProgramGenerator::goGenerator() { output_mgr_->OutputHeader(argc_, argv_, seed_); - GenerateAllTypes(); GenerateFunctions(); output_mgr_->Output(); diff --git a/src/RandomProgramGenerator.cpp b/src/RandomProgramGenerator.cpp index a8eb615b1..dc1e4c06a 100644 --- a/src/RandomProgramGenerator.cpp +++ b/src/RandomProgramGenerator.cpp @@ -176,6 +176,9 @@ static void print_help() cout << " --inline-function | --no-inline-function: enable | disable inline attributes on generated functions." << endl << endl; cout << " --inline-function-prob : set the probability of each function being marked as inline (default is 50)." << endl << endl; + //GCC C extensions + cout << " --computed-goto | --no-computed-goto: enable | disable computed goto extension (disable by default)." << endl << endl; + // numbered controls cout << " --max-array-dim : limit array dimensions to . (default 3)" << endl << endl; cout << " --max-array-len-per-dim : limit array length per dimension to (default 10)." << endl << endl; @@ -850,6 +853,16 @@ main(int argc, char **argv) continue; } + if (strcmp (argv[i], "--computed-goto") == 0) { + CGOptions::computed_goto(true); + continue; + } + + if (strcmp (argv[i], "--no-computed-goto") == 0) { + CGOptions::computed_goto(false); + continue; + } + if (strcmp (argv[i], "--no-jumps") == 0) { CGOptions::jumps(false); continue; diff --git a/src/StatementGoto.cpp b/src/StatementGoto.cpp index 73073a4f8..50144770a 100644 --- a/src/StatementGoto.cpp +++ b/src/StatementGoto.cpp @@ -260,7 +260,11 @@ StatementGoto::Output(std::ostream &out, FactMgr* /*fm*/, int indent) const out << ")"; outputln(out); output_tab(out, indent+1); - out << "goto " << label << ";"; + + if(CGOptions::computed_goto()) + out << "goto " << other_name_for_label << ";"; + else + out << "goto " << label << ";"; outputln(out); } @@ -416,6 +420,27 @@ StatementGoto::doFinalization(void) stm_labels.clear(); } +void +StatementGoto::change_label(std::vector addr_labels) const{ + string find_label=""; + find_label+="&&"; + find_label+=label; + auto it = std::find(addr_labels.begin(),addr_labels.end(),find_label); + int index; + if(it == addr_labels.end()){ + assert ("LABEL NOT FOUND"); + } + else{ + index = std::distance (addr_labels.begin(),it); + } + std::stringstream ss; + ss.clear(); + ss<< "*target["; + ss< init_skipped_vars; static std::map stm_labels; + + mutable std::string other_name_for_label; + void change_label(std::vector addr_labels) const; }; ///////////////////////////////////////////////////////////////////////////////