Fix bug in datatype narrowing algorithm affecting IL code.
authorMario de Sousa <msousa@fe.up.pt>
Mon, 03 Jul 2017 20:31:47 +0100
changeset 1054 57c08195c962
parent 1053 e94368340160
child 1055 ce7b65e24676
Fix bug in datatype narrowing algorithm affecting IL code.
stage3/forced_narrow_candidate_datatypes.cc
stage3/forced_narrow_candidate_datatypes.hh
stage3/narrow_candidate_datatypes.cc
stage3/narrow_candidate_datatypes.hh
--- a/stage3/forced_narrow_candidate_datatypes.cc	Mon Jul 03 20:28:26 2017 +0100
+++ b/stage3/forced_narrow_candidate_datatypes.cc	Mon Jul 03 20:31:47 2017 +0100
@@ -120,6 +120,30 @@
 
 
 
+void forced_narrow_candidate_datatypes_c::set_datatype_in_prev_il_instructions(symbol_c *datatype, il_instruction_c *symbol) {
+	if (NULL == symbol) ERROR;
+	/* In the forced_narrow_candidate_datatypes algorithm, we do NOT set any datatypes to invalid_type_name_c
+	 * Any IL instructions that really are of an invalid_type_name_c (because the IL code is buggy?) have already
+	 * been set by the standard narrow_candidate_datatypes algorithm.
+	 * 
+	 * Remember too that valid IL code may also have some IL instructions correctly set to invalid_type_name_c, especially
+	 * in cases where the data in the accumulator will not be used in the current IL instruction
+	 * For example:
+	 *        LD   bool_var
+	 *        JMPC label1
+	 *        LD 34
+	 *        ST int_var
+	 * lable1:            <----  This IL instruction_c (with NULL symbol->il_instruction) has invalid_type_name_c datatype!!
+	 *        LD T#3s              And yet, the code is legal!!!
+	 *        ST time_var
+	 */ 
+	if (!get_datatype_info_c::is_type_valid(datatype)) return;
+	// Call the 'original' version of the set_datatype_in_prev_il_instructions() function, from narrow_candidate_datatypes_c
+	return narrow_candidate_datatypes_c::set_datatype_in_prev_il_instructions(datatype, symbol);
+}
+
+
+
 void forced_narrow_candidate_datatypes_c::forced_narrow_il_instruction(symbol_c *symbol, std::vector <symbol_c *> &next_il_instruction) {
   if (NULL == symbol->datatype) {
     if (symbol->candidate_datatypes.empty()) {
--- a/stage3/forced_narrow_candidate_datatypes.hh	Mon Jul 03 20:28:26 2017 +0100
+++ b/stage3/forced_narrow_candidate_datatypes.hh	Mon Jul 03 20:31:47 2017 +0100
@@ -48,10 +48,13 @@
   private:
     void forced_narrow_il_instruction(symbol_c *symbol, std::vector <symbol_c *> &next_il_instruction);
     
+  protected:   
+    virtual void set_datatype_in_prev_il_instructions(symbol_c *datatype, il_instruction_c *symbol);
+
   public:
     forced_narrow_candidate_datatypes_c(symbol_c *ignore);
     virtual ~forced_narrow_candidate_datatypes_c(void);
-   
+
     /****************************************/
     /* B.2 - Language IL (Instruction List) */
     /****************************************/
--- a/stage3/narrow_candidate_datatypes.cc	Mon Jul 03 20:28:26 2017 +0100
+++ b/stage3/narrow_candidate_datatypes.cc	Mon Jul 03 20:31:47 2017 +0100
@@ -107,8 +107,8 @@
 
 
 /* Only set the symbol's desired datatype to 'datatype' if that datatype is in the candidate_datatype list */
-// static void set_datatype_in_prev_il_instructions(symbol_c *datatype, std::vector <symbol_c *> prev_il_instructions) {
-static void set_datatype_in_prev_il_instructions(symbol_c *datatype, il_instruction_c *symbol) {
+// NOTE: This function is virtual! The forced_narrow_candidate_datatypes_c has a slightly different version of this fuinction!!
+void narrow_candidate_datatypes_c::set_datatype_in_prev_il_instructions(symbol_c *datatype, il_instruction_c *symbol) {
 	if (NULL == symbol) ERROR;
 	for (unsigned int i = 0; i < symbol->prev_il_instruction.size(); i++)
 		set_datatype(datatype, symbol->prev_il_instruction[i]);
@@ -1281,6 +1281,7 @@
  *       So, if yoy wish to set the prev_il_instruction->datatype = symbol->datatype;
  *       do it __before__ calling set_il_operand_datatype() (which in turn calls il_operand->accept(*this)) !!
  */
+int  count = 0;
 void *narrow_candidate_datatypes_c::set_il_operand_datatype(symbol_c *il_operand, symbol_c *datatype) {
 	if (NULL == il_operand) return NULL; /* if no IL operand => error in the source code!! */
 
--- a/stage3/narrow_candidate_datatypes.hh	Mon Jul 03 20:28:26 2017 +0100
+++ b/stage3/narrow_candidate_datatypes.hh	Mon Jul 03 20:31:47 2017 +0100
@@ -69,6 +69,10 @@
     il_instruction_c *fake_prev_il_instruction;
     il_instruction_c   *current_il_instruction;
 
+  protected:  
+    virtual void set_datatype_in_prev_il_instructions(symbol_c *datatype, il_instruction_c *symbol);
+
+  private:
     bool is_widening_compatible(const struct widen_entry widen_table[], symbol_c *left_type, symbol_c *right_type, symbol_c *result_type, bool *deprecated_status = NULL);
 
     void *narrow_spec_init           (symbol_c *symbol, symbol_c *type_decl, symbol_c *init_value);