# HG changeset patch # User Mario de Sousa # Date 1328468952 0 # Node ID 78f31e12fc5226b2045a7b6945571e42a87cc4f1 # Parent c8e6cf57324a40d6de33c0bbe130390bc9967aeb Better identification of erros in function/FB invocations. diff -r c8e6cf57324a -r 78f31e12fc52 absyntax_utils/function_param_iterator.cc --- a/absyntax_utils/function_param_iterator.cc Fri Feb 03 18:16:20 2012 +0000 +++ b/absyntax_utils/function_param_iterator.cc Sun Feb 05 19:09:12 2012 +0000 @@ -225,7 +225,8 @@ function_block_declaration_c *fb_decl = dynamic_cast(pou_decl); program_declaration_c * p_decl = dynamic_cast(pou_decl); - if ((NULL == f_decl) && (NULL == fb_decl) && (NULL == p_decl)) ERROR; + if ((NULL == f_decl) && (NULL == fb_decl) && (NULL == p_decl)) + ERROR; /* OK. Now initialise this object... */ this->f_decl = pou_decl; diff -r c8e6cf57324a -r 78f31e12fc52 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Fri Feb 03 18:16:20 2012 +0000 +++ b/stage3/fill_candidate_datatypes.cc Sun Feb 05 19:09:12 2012 +0000 @@ -1692,7 +1692,22 @@ /* Look for all compatible function declarations, and add their return datatypes * to the candidate_datatype list of this function invocation. + * + * If only one function exists, we add its return datatype to the candidate_datatype list, + * even if the parameters passed to it are invalid. + * This guarantees that the remainder of the expression in which the function call is inserted + * is treated as if the function call returns correctly, and therefore does not generate + * spurious error messages. + * Even if the parameters to the function call are invalid, doing this is still safe, as the + * expressions inside the function call will themselves have erros and will guarantee that + * compilation is aborted in stage3. */ + if (function_symtable.multiplicity(symbol->function_name) == 1) { + f_decl = function_symtable.get_value(lower); + returned_parameter_type = base_type(f_decl->type_name); + symbol->candidate_functions.push_back(f_decl); + symbol->candidate_datatypes.push_back(returned_parameter_type); + } for(; lower != upper; lower++) { bool compatible = false; diff -r c8e6cf57324a -r 78f31e12fc52 stage3/narrow_candidate_datatypes.cc --- a/stage3/narrow_candidate_datatypes.cc Fri Feb 03 18:16:20 2012 +0000 +++ b/stage3/narrow_candidate_datatypes.cc Sun Feb 05 19:09:12 2012 +0000 @@ -141,7 +141,6 @@ unsigned int i; if (NULL != ext_parm_count) *ext_parm_count = -1; - /* Iterating through the formal parameters of the function call */ while((call_param_name = fcp_iterator.next_f()) != NULL) { @@ -1025,6 +1024,7 @@ /* set the called_function_declaration. */ symbol->called_function_declaration = NULL; +#if 0 if (symbol->candidate_datatypes.size() == 1) { /* If only one possible called function, then that is the function to call! * In this case we ignore the symbol->datatype value (that may even be NULL). @@ -1037,10 +1037,10 @@ symbol->called_function_declaration = symbol->candidate_functions[0]; if ((NULL != symbol->datatype) && (!is_type_equal(symbol->candidate_datatypes[0], symbol->datatype))) ERROR; - } - else { + } else +#endif + { /* set the called_function_declaration taking into account the datatype that we need to return */ - symbol->called_function_declaration = NULL; for(unsigned int i = 0; i < symbol->candidate_datatypes.size(); i++) { if (is_type_equal(symbol->candidate_datatypes[i], symbol->datatype)) { symbol->called_function_declaration = symbol->candidate_functions[i]; @@ -1052,10 +1052,27 @@ * necessarily an internal compiler error. It could be because the symbol->datatype is NULL * (because the ST code being analysed has an error _before_ this function invocation). * However, we don't just give, up, we carry on recursivly analysing the code, so as to be - * able to print out any error messages related to underlying code that could be partially correct. + * able to print out any error messages related to the parameters being passed in this function + * invocation. */ /* if (NULL == symbol->called_function_declaration) ERROR; */ - + + if (symbol->candidate_datatypes.size() == 1) { + /* If only one function declaration, then we use that (even if symbol->datatypes == NULL) + * so we can check for errors in the expressions used to pass parameters in this + * function invocation. + */ + symbol->called_function_declaration = symbol->candidate_functions[0]; + } + /* If an overloaded function is being invoked, and we cannot determine which version to use, + * then we can not meaningfully verify the expressions used inside that function invocation. + * We simply give up! + */ + if (NULL == symbol->called_function_declaration) { +printf("giving up!\n"); + return NULL; + } + if (NULL != symbol->nonformal_param_list) narrow_nonformal_call(symbol, symbol->called_function_declaration, &ext_parm_count); if (NULL != symbol-> formal_param_list) narrow_formal_call(symbol, symbol->called_function_declaration, &ext_parm_count); symbol->extensible_param_count = ext_parm_count; diff -r c8e6cf57324a -r 78f31e12fc52 stage3/print_datatypes_error.cc --- a/stage3/print_datatypes_error.cc Fri Feb 03 18:16:20 2012 +0000 +++ b/stage3/print_datatypes_error.cc Sun Feb 05 19:09:12 2012 +0000 @@ -470,8 +470,6 @@ } void *print_datatypes_error_c::visit(LDN_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -481,7 +479,6 @@ } void *print_datatypes_error_c::visit(ST_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; /* MANU: * if prev_instruction is NULL we can print a message error or warning error like: * we can't use a ST like first instruction. @@ -496,7 +493,6 @@ } void *print_datatypes_error_c::visit(STN_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; /* MANU: * if prev_instruction is NULL we can print a message error or warning error like: * we can't use a ST like first instruction. @@ -516,8 +512,6 @@ } void *print_datatypes_error_c::visit(S_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -527,8 +521,6 @@ } void *print_datatypes_error_c::visit(R_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -538,8 +530,6 @@ } void *print_datatypes_error_c::visit(S1_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -549,8 +539,6 @@ } void *print_datatypes_error_c::visit(R1_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -590,8 +578,6 @@ } void *print_datatypes_error_c::visit(AND_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -601,8 +587,6 @@ } void *print_datatypes_error_c::visit(OR_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -612,8 +596,6 @@ } void *print_datatypes_error_c::visit(XOR_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -623,8 +605,6 @@ } void *print_datatypes_error_c::visit(ANDN_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -634,8 +614,6 @@ } void *print_datatypes_error_c::visit(ORN_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -645,8 +623,6 @@ } void *print_datatypes_error_c::visit(XORN_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -656,8 +632,6 @@ } void *print_datatypes_error_c::visit(ADD_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -667,8 +641,6 @@ } void *print_datatypes_error_c::visit(SUB_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -678,8 +650,6 @@ } void *print_datatypes_error_c::visit(MUL_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -689,8 +659,6 @@ } void *print_datatypes_error_c::visit(DIV_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -700,8 +668,6 @@ } void *print_datatypes_error_c::visit(MOD_operator_c *symbol) { - if (NULL != symbol->datatype) return NULL; - il_operand->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (il_operand->candidate_datatypes.size() > 0)) @@ -798,8 +764,6 @@ /***********************/ void *print_datatypes_error_c::visit(or_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -811,8 +775,6 @@ void *print_datatypes_error_c::visit(xor_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -824,8 +786,6 @@ void *print_datatypes_error_c::visit(and_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -837,8 +797,6 @@ void *print_datatypes_error_c::visit(equ_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -850,8 +808,6 @@ void *print_datatypes_error_c::visit(notequ_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -863,8 +819,6 @@ void *print_datatypes_error_c::visit(lt_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -876,8 +830,6 @@ void *print_datatypes_error_c::visit(gt_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -889,8 +841,6 @@ void *print_datatypes_error_c::visit(le_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -902,8 +852,6 @@ void *print_datatypes_error_c::visit(ge_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -915,14 +863,12 @@ void *print_datatypes_error_c::visit(add_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - - symbol->l_exp->accept(*this); - symbol->r_exp->accept(*this); - if ((symbol->candidate_datatypes.size() == 0) && - (symbol->l_exp->candidate_datatypes.size() > 0) && - (symbol->r_exp->candidate_datatypes.size() > 0)) - STAGE3_ERROR(symbol, symbol, "Current '+' result and operand not of same data type."); + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if ((symbol->candidate_datatypes.size() == 0) && + (symbol->l_exp->candidate_datatypes.size() > 0) && + (symbol->r_exp->candidate_datatypes.size() > 0)) + STAGE3_ERROR(symbol, symbol, "Data type mismatch for '+' expression."); return NULL; } @@ -930,58 +876,48 @@ void *print_datatypes_error_c::visit(sub_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - - symbol->l_exp->accept(*this); - symbol->r_exp->accept(*this); - if ((symbol->candidate_datatypes.size() == 0) && - (symbol->l_exp->candidate_datatypes.size() > 0) && - (symbol->r_exp->candidate_datatypes.size() > 0)) - STAGE3_ERROR(symbol, symbol, "Current '-' result and operand not of same data type."); + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if ((symbol->candidate_datatypes.size() == 0) && + (symbol->l_exp->candidate_datatypes.size() > 0) && + (symbol->r_exp->candidate_datatypes.size() > 0)) + STAGE3_ERROR(symbol, symbol, "Data type mismatch for '-' expression."); return NULL; } void *print_datatypes_error_c::visit(mul_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - - symbol->l_exp->accept(*this); - symbol->r_exp->accept(*this); - if ((symbol->candidate_datatypes.size() == 0) && - (symbol->l_exp->candidate_datatypes.size() > 0) && - (symbol->r_exp->candidate_datatypes.size() > 0)) - STAGE3_ERROR(symbol, symbol, "Current '*' result and operand not of same data type."); + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if ((symbol->candidate_datatypes.size() == 0) && + (symbol->l_exp->candidate_datatypes.size() > 0) && + (symbol->r_exp->candidate_datatypes.size() > 0)) + STAGE3_ERROR(symbol, symbol, "Data type mismatch for '*' expression."); return NULL; } void *print_datatypes_error_c::visit(div_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - - symbol->l_exp->accept(*this); - symbol->r_exp->accept(*this); - if ((symbol->candidate_datatypes.size() == 0) && - (symbol->l_exp->candidate_datatypes.size() > 0) && - (symbol->r_exp->candidate_datatypes.size() > 0)) - STAGE3_ERROR(symbol, symbol, "Current '/' result and operand not of same data type."); + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if ((symbol->candidate_datatypes.size() == 0) && + (symbol->l_exp->candidate_datatypes.size() > 0) && + (symbol->r_exp->candidate_datatypes.size() > 0)) + STAGE3_ERROR(symbol, symbol, "Data type mismatch for '/' expression."); return NULL; } void *print_datatypes_error_c::visit(mod_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - - symbol->l_exp->accept(*this); - symbol->r_exp->accept(*this); - if ((symbol->candidate_datatypes.size() == 0) && - (symbol->l_exp->candidate_datatypes.size() > 0) && - (symbol->r_exp->candidate_datatypes.size() > 0)) - STAGE3_ERROR(symbol, symbol, "Current 'MOD' result and operand not of same data type."); + symbol->l_exp->accept(*this); + symbol->r_exp->accept(*this); + if ((symbol->candidate_datatypes.size() == 0) && + (symbol->l_exp->candidate_datatypes.size() > 0) && + (symbol->r_exp->candidate_datatypes.size() > 0)) + STAGE3_ERROR(symbol, symbol, "Data type mismatch for 'MOD' expression."); return NULL; } void *print_datatypes_error_c::visit(power_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->l_exp->accept(*this); symbol->r_exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && @@ -993,8 +929,6 @@ void *print_datatypes_error_c::visit(neg_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (symbol->exp->candidate_datatypes.size() > 0)) @@ -1004,8 +938,6 @@ void *print_datatypes_error_c::visit(not_expression_c *symbol) { - if (NULL != symbol->datatype) return NULL; - symbol->exp->accept(*this); if ((symbol->candidate_datatypes.size() == 0) && (symbol->exp->candidate_datatypes.size() > 0)) @@ -1015,27 +947,35 @@ void *print_datatypes_error_c::visit(function_invocation_c *symbol) { - list_c *parameter_list; - - if (NULL != symbol->formal_param_list) - parameter_list = (list_c *)symbol->formal_param_list; - else if (NULL != symbol->nonformal_param_list) - parameter_list = (list_c *)symbol->nonformal_param_list; - else ERROR; - - parameter_list->accept(*this); - - if (symbol->candidate_datatypes.size() == 0) { + symbol_c *param_value, *param_name; + function_call_param_iterator_c fcp_iterator(symbol); + bool function_invocation_error = false; + + if ((NULL != symbol->formal_param_list) && (NULL != symbol->nonformal_param_list)) + ERROR; + + if (NULL != symbol->formal_param_list) { + symbol->formal_param_list->accept(*this); + while ((param_name = fcp_iterator.next_f()) != NULL) { + param_value = fcp_iterator.get_current_value(); + if (NULL == param_value->datatype) { + function_invocation_error = true; + } + } + } + if (NULL != symbol->nonformal_param_list) { + symbol->nonformal_param_list->accept(*this); + while ((param_value = fcp_iterator.next_nf()) != NULL) { + if (NULL == param_value->datatype) { + function_invocation_error = true; + } + } + } + + if (function_invocation_error) { /* No compatible function exists */ STAGE3_ERROR(symbol, symbol, "Invalid parameters in function invocation: %s\n", ((identifier_c *)symbol->function_name)->value); } -#if 0 - else - if (NULL == symbol->datatype) { - /* One or compatible functions exists, but none chosen! */ - STAGE3_ERROR(symbol, symbol, "Invalid parameters in function invocation: %s\n", f_name->value); - } -#endif return NULL; } @@ -1075,17 +1015,32 @@ */ // SYM_REF3(fb_invocation_c, fb_name, formal_param_list, nonformal_param_list, symbol_c *called_fb_declaration;) void *print_datatypes_error_c::visit(fb_invocation_c *symbol) { - list_c *parameter_list; - - if (NULL != symbol->formal_param_list) - parameter_list = (list_c *)symbol->formal_param_list; - else if (NULL != symbol->nonformal_param_list) - parameter_list = (list_c *)symbol->nonformal_param_list; - else ERROR; - - parameter_list->accept(*this); - - if (NULL == symbol->called_fb_declaration) { + symbol_c *param_value, *param_name; + function_call_param_iterator_c fcp_iterator(symbol); + bool function_invocation_error = false; + + if ((NULL != symbol->formal_param_list) && (NULL != symbol->nonformal_param_list)) + ERROR; + + if (NULL != symbol->formal_param_list) { + symbol->formal_param_list->accept(*this); + while ((param_name = fcp_iterator.next_f()) != NULL) { + param_value = fcp_iterator.get_current_value(); + if (NULL == param_value->datatype) { + function_invocation_error = true; + } + } + } + if (NULL != symbol->nonformal_param_list) { + symbol->nonformal_param_list->accept(*this); + while ((param_value = fcp_iterator.next_nf()) != NULL) { + if (NULL == param_value->datatype) { + function_invocation_error = true; + } + } + } + + if (function_invocation_error) { /* Invalid parameters for FB call! */ STAGE3_ERROR(symbol, symbol, "Invalid parameters in FB invocation: %s\n", ((identifier_c *)symbol->fb_name)->value); }