Correctly handle JMP and RET IL operators in flow control analysis.
authorMario de Sousa <msousa@fe.up.pt>
Sat, 03 Mar 2012 20:27:20 +0000
changeset 463 fafa9abc166e
parent 462 f7dada0a8952
child 464 319ee8b218f3
Correctly handle JMP and RET IL operators in flow control analysis.
stage3/flow_control_analysis.cc
stage3/flow_control_analysis.hh
--- a/stage3/flow_control_analysis.cc	Sat Mar 03 13:07:00 2012 +0000
+++ b/stage3/flow_control_analysis.cc	Sat Mar 03 20:27:20 2012 +0000
@@ -180,6 +180,7 @@
 /*| instruction_list il_instruction */
 // SYM_LIST(instruction_list_c)
 void *flow_control_analysis_c::visit(instruction_list_c *symbol) {
+	prev_il_instruction_is_JMP_or_RET = false;
 	for(int i = 0; i < symbol->n; i++) {
 		prev_il_instruction = NULL;
 		if (i > 0) prev_il_instruction = symbol->elements[i-1];
@@ -194,10 +195,11 @@
 // SYM_REF2(il_instruction_c, label, il_instruction)
 // void *visit(instruction_list_c *symbol);
 void *flow_control_analysis_c::visit(il_instruction_c *symbol) {
-	if (NULL != prev_il_instruction)
+	if ((NULL != prev_il_instruction) && (!prev_il_instruction_is_JMP_or_RET))
 		symbol->prev_il_instruction.push_back(prev_il_instruction);
 
-	/* check if it is an il_expression_c, or a JMP[C[N]] and if so, handle it correctly */
+	/* check if it is an il_expression_c, a JMP[C[N]], or a RET, and if so, handle it correctly */
+	prev_il_instruction_is_JMP_or_RET = false;
 	if (NULL != symbol->il_instruction)
 		symbol->il_instruction->accept(*this);
 	return NULL;
@@ -238,7 +240,8 @@
   /* search for the il_instruction_c containing the label */
   il_instruction_c *destination = search_il_label->find_label(symbol->label);
 
-  /* TODO: for JMP and RET (unconditional) instructions, make sure the next IL instruction does not point back! */
+  /* give the visit(JMP_operator *) an oportunity to set the prev_il_instruction_is_JMP_or_RET flag! */
+  symbol->il_jump_operator->accept(*this);
   /* add, to that il_instruction's list of prev_il_intsructions, the curr_il_instruction */
   if (NULL != destination)
     destination->prev_il_instruction.push_back(curr_il_instruction);
@@ -330,10 +333,22 @@
 // void *visit(  CAL_operator_c *symbol);
 // void *visit( CALC_operator_c *symbol);
 // void *visit(CALCN_operator_c *symbol);
-// void *visit(  RET_operator_c *symbol);
+
+/* this next visit function will be called directly from visit(il_instruction_c *) */
+void *flow_control_analysis_c::visit(  RET_operator_c *symbol) {
+	prev_il_instruction_is_JMP_or_RET = true;
+	return NULL;
+}
+
 // void *visit( RETC_operator_c *symbol);
 // void *visit(RETCN_operator_c *symbol);
-// void *visit(  JMP_operator_c *symbol);
+
+/* this next visit function will be called from visit(il_jump_operation_c *) */
+void *flow_control_analysis_c::visit(  JMP_operator_c *symbol) {
+	prev_il_instruction_is_JMP_or_RET = true;
+	return NULL;
+}
+
 // void *visit( JMPC_operator_c *symbol);
 // void *visit(JMPCN_operator_c *symbol);
 
--- a/stage3/flow_control_analysis.hh	Sat Mar 03 13:07:00 2012 +0000
+++ b/stage3/flow_control_analysis.hh	Sat Mar 03 20:27:20 2012 +0000
@@ -51,6 +51,7 @@
     search_il_label_c *search_il_label;
     symbol_c *prev_il_instruction;
     symbol_c *curr_il_instruction;
+    bool      prev_il_instruction_is_JMP_or_RET;
 
   public:
     flow_control_analysis_c(symbol_c *ignore);
@@ -138,10 +139,10 @@
 //     void *visit(  CAL_operator_c *symbol);
 //     void *visit( CALC_operator_c *symbol);
 //     void *visit(CALCN_operator_c *symbol);
-//     void *visit(  RET_operator_c *symbol);
+     void *visit(  RET_operator_c *symbol);
 //     void *visit( RETC_operator_c *symbol);
 //     void *visit(RETCN_operator_c *symbol);
-//     void *visit(  JMP_operator_c *symbol);
+     void *visit(  JMP_operator_c *symbol);
 //     void *visit( JMPC_operator_c *symbol);
 //     void *visit(JMPCN_operator_c *symbol);