diff -r 871edf12fe64 -r 214d3fdee596 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Tue Apr 05 17:12:12 2011 +0100 +++ b/stage4/generate_c/generate_c.cc Tue Apr 05 18:31:55 2011 +0100 @@ -136,6 +136,10 @@ #define TEMP_VAR VAR_LEADER "TMP_" #define SOURCE_VAR VAR_LEADER "SRC_" +/* please see the comment before the RET_operator_c visitor for details... */ +#define END_LABEL VAR_LEADER "end" + + /***********************************************************************/ /***********************************************************************/ /***********************************************************************/ @@ -426,6 +430,43 @@ }; virtual ~generate_c_pous_c(void) {} + private: + void print_end_of_block_label(void) { + /* Print and __end label for return statements! + * If label is not used by at least one goto, compiler will generate a warning. + * To work around this we introduce the useless goto. + */ + s4o.print("\n"); + s4o.print(s4o.indent_spaces); + s4o.print("/* to humour the compiler, we insert a goto */\n"); + s4o.print(s4o.indent_spaces); + s4o.print("goto "); + s4o.print(END_LABEL); + s4o.print(";\n"); + s4o.indent_left(); + + /* write the label marking the end of the code block */ + /* please see the comment before the RET_operator_c visitor for details... */ + /* also needed for return_statement_c */ + s4o.print("\n"); + s4o.print(s4o.indent_spaces); + s4o.print(END_LABEL); + s4o.print(":\n"); + s4o.indent_right(); + + /* since every label must be followed by at least one statement, and + * only the functions will introduce the return statement after this label, + * function blocks written in IL would result in invalid C++ code. + * To work around this we introduce the equivalent of a 'nop' operation + * to humour the compiler... + */ + s4o.print(s4o.indent_spaces); + s4o.print("/* to humour the compiler, we insert a nop */\n"); + s4o.print(s4o.indent_spaces); + s4o.print("if (0);\n\n"); + } + + public: /********************/ @@ -593,6 +634,8 @@ generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->derived_function_name, symbol); symbol->function_body->accept(generate_c_code); + print_end_of_block_label(); + vardecl = new generate_c_vardecl_c(&s4o, generate_c_vardecl_c::foutputassign_vf, generate_c_vardecl_c::output_vt | @@ -776,6 +819,7 @@ /* (C.5) Function code */ generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->fblock_name, symbol, FB_FUNCTION_PARAM"->"); symbol->fblock_body->accept(generate_c_code); + print_end_of_block_label(); s4o.indent_left(); s4o.print(s4o.indent_spaces + "} // "); symbol->fblock_name->accept(*this); @@ -936,6 +980,7 @@ /* (C.5) Function code */ generate_c_SFC_IL_ST_c generate_c_code(&s4o, symbol->program_type_name, symbol, FB_FUNCTION_PARAM"->"); symbol->function_block_body->accept(generate_c_code); + print_end_of_block_label(); s4o.indent_left(); s4o.print(s4o.indent_spaces + "} // "); symbol->program_type_name->accept(*this);