def error_check_comparison_recursive_target(self, token, left_token,
                                             right_token):
     ''' COMPARISON OPERATORS - MUST BE THE SAME ON BOTH SIDES
         input:  token   cppcheck token object
                 left_token, right_token
         returns: nothing, with possible side effect of adding errors
         '''
     if self.debug_verbose and self.cps_units_checker:
         self.cps_units_checker.handle_debug_verbose(inspect.stack()[0][3])
     if token.isComparisonOp:
         if left_token and left_token.units and right_token and right_token.units:  # BOTH HAVE UNITS
             if left_token.units != right_token.units:
                 # CREATE VARIABLE ERROR OBJECT
                 new_error = UnitError(self.cps_units_checker)
                 new_error.var_name = ''  # NO VAR NAME SINCE ITS A COMPARISON OPERATORS
                 new_error.ERROR_TYPE = UnitErrorTypes.COMPARISON_INCOMPATIBLE_UNITS
                 # LINENR
                 new_error.linenr = token.linenr
                 new_error.token_left = left_token
                 new_error.token_right = right_token
                 new_error.token = token
                 # new_error.is_unit_propagation_based_on_constants = inner_dict['is_unit_propagation_based_on_constants']
                 # new_error.is_unit_propagation_based_on_unknown_variable = inner_dict['is_unit_propagation_based_on_unknown_variable']
                 # if inner_dict['is_unit_propagation_based_on_constants'] or inner_dict['is_unit_propagation_based_on_unknown_variable']:
                 # new_error.is_warning = True
                 # GET LINE FROM ORIGINAL FILE IF IT EXISTS
                 if self.source_file_exists:
                     new_error.source_code_at_first_assignment = self.source_file_lines[
                         new_error.linenr_at_first_unit_assignment -
                         1].strip()
                     new_error.source_code_when_multiple_units_happened = self.source_file_lines[
                         new_error.linenr_of_multiple_unit_assignment -
                         1].strip()
                 # COLLECT ERROR
                 self.all_errors.append(new_error)
 def error_check_function_args_consistent(self,
                                          cppcheck_configuration_unit):
     ''' VERIFIES UNIT CONSISTENCY OF FUNCTIONS AT EVERY CALL POINT
         input: cppcheck configuration unit from dump
         returns: none
         side_effects:  might add UnitError objects to self.all_errors list
         '''
     # FOR EACH FUNCTION
     for f in cppcheck_configuration_unit.functions:
         # FOR EACH ARG IN A FUNCTION
         for arg_list_of_call_points in f.arg_units:
             # FOR EACH TIME THE FUNCTION WAS CALLED
             error_found = False
             new_error = UnitError(self.cps_units_checker)
             first_call_point_with_units = None
             for call_point in arg_list_of_call_points:
                 # FIND SOME CALL POINT WITH UNITS
                 if not first_call_point_with_units:
                     if call_point['units']:
                         if self.debug:
                             print 'CALL POINT UNITS:' + str(
                                 call_point['units'])
                         first_call_point_with_units = call_point
                     continue
                 # CHECK UNITS OF FIRST CALL POINT AGAINST ALL OTHERS
                 #HAS UNITS  and UNITS ARE DIFFERENT THAN SOME OTHER CALL POINT
                 if call_point['units'] and (
                         call_point['units'] !=
                         first_call_point_with_units['units']):
                     error_found = True
                     # FOUND DIFFERENT UNITS AT TWO DIFFERENT CALL POINTS
                     new_error.var_name = f.name
                     new_error.ERROR_TYPE = UnitErrorTypes.FUNCTION_CALLED_WITH_DIFFERENT_UNIT_ARGUMENTS
                     new_error.token = first_call_point_with_units['token']
                     new_error.f = first_call_point_with_units['token']
                     # FIRST ASSIGNMENT
                     new_error.set_primary_line_number(
                         first_call_point_with_units['linenr'])
                     new_error.linenr_at_first_unit_assignment = first_call_point_with_units[
                         'linenr']
                     new_error.units_at_first_assignment = first_call_point_with_units[
                         'units']
                     # SECOND (DIFFERENT) ASSIGNMENT
                     new_error.linenr_of_multiple_unit_assignment = call_point[
                         'linenr']
                     new_error.units_when_multiple_happened = call_point[
                         'units']
                     break  # FOR LOOP
             if error_found:
                 # GET LINE FROM ORIGINAL FILE IF IT EXISTS
                 if self.source_file_exists:
                     # todo: resolve relative link to different file and load source
                     if new_error.linenr_at_first_unit_assignment <= len(
                             self.source_file_lines):
                         if new_error.linenr_of_multiple_unit_assignment <= len(
                                 self.source_file_lines):
                             new_error.source_code_at_first_assignment = self.source_file_lines[
                                 new_error.linenr_at_first_unit_assignment -
                                 1].strip()
                             new_error.source_code_when_multiple_units_happened = self.source_file_lines[
                                 new_error.
                                 linenr_of_multiple_unit_assignment -
                                 1].strip()
                 # COLLECT ERROR
                 self.all_errors.append(new_error)
 def error_check_multiple_units(self, cppcheck_configuration_unit):
     ''' MULTIPLE_UNIT_TYPE ASSIGNMENT ERROR CHECKING IMPLEMENTATION 
         input: cppcheck configuration unit from dump
         returns: none
         side_effects:  might add UnitError objects to self.all_errors list
         '''
     # SANITY DEFENSE
     if not cppcheck_configuration_unit:
         return
     vars_with_multi_units_dict = OrderedDict(
     )  # {scope_id: [list_of_vars_with_multi_units]}
     # SEARCH SCOPE OBJECTS FOR CHECK FOR ERRORS
     for s in cppcheck_configuration_unit.scopes:
         #if self.debug:
         #print '- '*42
         if s.var_ordered_dict:
             # FOR EACH VARIABLE
             for var_name, dict_of_assignments in s.var_ordered_dict.iteritems(
             ):
                 # have_found_multi_units_for_this_var = False
                 # FOR EACH LIST OF UNITS ASSIGNED TO A VARIABLE
                 for linenr, inner_dict in dict_of_assignments.iteritems():
                     units_list = inner_dict['units']
                     # TEST FOR MULTIPLE UNITS ASSIGNED
                     if len(units_list) > 1:
                         # CREATE VARIABLE ERROR/WARNING OBJECT
                         new_error = UnitError(self.cps_units_checker)
                         new_error.var_name = var_name
                         new_error.ERROR_TYPE = UnitErrorTypes.VARIABLE_MULTIPLE_UNITS
                         # LINENR OF FIRST ASSIGNMENT
                         new_error.linenr_at_first_unit_assignment = s.var_ordered_dict[
                             var_name].keys()[
                                 0]  # WORKS BECAUSE ORDERED DICT
                         # UNITS AT FIRST ASSIGNMENT
                         new_error.units_at_first_assignment = s.var_ordered_dict[
                             var_name].values()[0][
                                 'units']  # WORKS BECAUSE ORDERED DICT
                         new_error.all_units_assigned_to_var_as_dict = s.var_ordered_dict[
                             var_name]
                         new_error.token = s.var_ordered_dict[
                             var_name].values()[0][
                                 'token']  # WORKS BECAUSE ORDERED DICT
                         new_error.is_unit_propagation_based_on_constants = inner_dict[
                             'is_unit_propagation_based_on_constants']
                         new_error.is_unit_propagation_based_on_unknown_variable = inner_dict[
                             'is_unit_propagation_based_on_unknown_variable']
                         if inner_dict[
                                 'is_unit_propagation_based_on_constants'] or inner_dict[
                                     'is_unit_propagation_based_on_unknown_variable']:
                             new_error.is_warning = True
                         for linenr, units_list in s.var_ordered_dict[
                                 var_name].iteritems():
                             if 'units' in units_list:
                                 if len(units_list['units']) > 1:
                                     # LINENR AT ERROR ASSIGNMENT
                                     new_error.set_primary_line_number(
                                         linenr)
                                     # UNITS AT ERROR ASSIGNMENT
                                     new_error.units_when_multiple_happened = units_list
                                     break  # REPORT THE FIRST
                         # GET LINE FROM ORIGINAL FILE IF IT EXISTS
                         if self.source_file_exists:
                             if new_error.linenr_at_first_unit_assignment <= len(
                                     self.source_file_lines):
                                 if new_error.linenr_of_multiple_unit_assignment <= len(
                                         self.source_file_lines):
                                     new_error.source_code_at_first_assignment = self.source_file_lines[
                                         new_error.
                                         linenr_at_first_unit_assignment -
                                         1].strip()
                                     new_error.source_code_when_multiple_units_happened = self.source_file_lines[
                                         new_error.
                                         linenr_of_multiple_unit_assignment
                                         - 1].strip()
                         # WAS VARIABLE ASSIGNED MULTIPLE UNITS
                         if new_error.linenr_at_first_unit_assignment != new_error.linenr_of_multiple_unit_assignment:
                             new_error.was_assigned_mutiple_units = True
                         # COLLECT ERROR / WARNING
                         self.all_errors.append(new_error)
                         # MULTIPLE UNITS DETECTED
                         # have_found_multi_units_for_this_var = True
                         break
    def error_check_unit_smell(self, cppcheck_configuration_unit):
        ''' UNIT_SMELL ERROR CHECKING IMPLEMENTATION 
            input: cppcheck configuration unit from dump
            returns: none
            side_effects:  might add UnitError objects to self.all_errors list
            '''
        # SANITY DEFENSE
        if not cppcheck_configuration_unit:
            return
# SEARCH SCOPE OBJECTS FOR ERRORS
        for s in cppcheck_configuration_unit.scopes:
            if s.var_ordered_dict:
                # FOR EACH VARIABLE
                for var_name, dict_of_assignments in s.var_ordered_dict.iteritems(
                ):
                    # FOR EACH LIST OF UNITS ASSIGNED TO A VARIABLE
                    for linenr, inner_dict in dict_of_assignments.iteritems():
                        units_list = inner_dict['units']
                        # TEST FOR MULTIPLE UNITS ASSIGNED
                        for u in units_list:
                            # WRITES ALL UNITS OUT TO A FILE FOR EMPIRICALLY LOOKING FOR UNUSUAL UNITS
                            # with open('2016_07_20_1026_list_of_all_units.txt', 'a') as f:
                            # f.write(str(u) + "\n")
                            if u not in self.symbol_helper.list_of_vetted_units:
                                # CREATE VARIABLE ERROR/WARNING OBJECT
                                new_error = UnitError(self.cps_units_checker)
                                new_error.var_name = var_name
                                new_error.ERROR_TYPE = UnitErrorTypes.UNIT_SMELL
                                # LINENR OF FIRST ASSIGNMENT
                                new_error.linenr_at_first_unit_assignment = s.var_ordered_dict[
                                    var_name].keys()[
                                        0]  # WORKS BECAUSE ORDERED DICT
                                new_error.set_primary_line_number(
                                    s.var_ordered_dict[var_name].keys()
                                    [0])  # WORKS BECAUSE ORDERED DICT
                                # UNITS AT FIRST ASSIGNMENT
                                new_error.units_at_first_assignment = s.var_ordered_dict[
                                    var_name].values()[0][
                                        'units']  # WORKS BECAUSE ORDERED DICT
                                new_error.all_units_assigned_to_var_as_dict = s.var_ordered_dict[
                                    var_name]
                                new_error.token = s.var_ordered_dict[
                                    var_name].values()[0][
                                        'token']  # WORKS BECAUSE ORDERED DICT
                                new_error.is_unit_propagation_based_on_constants = inner_dict[
                                    'is_unit_propagation_based_on_constants']
                                new_error.is_unit_propagation_based_on_unknown_variable = inner_dict[
                                    'is_unit_propagation_based_on_unknown_variable']
                                if inner_dict[
                                        'is_unit_propagation_based_on_constants'] or inner_dict[
                                            'is_unit_propagation_based_on_unknown_variable']:
                                    new_error.is_warning = True
                                # GET LINE FROM ORIGINAL FILE IF IT EXISTS
                                if self.source_file_exists:
                                    if new_error.linenr_at_first_unit_assignment <= len(
                                            self.source_file_lines):
                                        if new_error.linenr_of_multiple_unit_assignment <= len(
                                                self.source_file_lines):
                                            new_error.source_code_at_first_assignment = self.source_file_lines[
                                                new_error.
                                                linenr_at_first_unit_assignment
                                                - 1].strip()
                                            new_error.source_code_when_multiple_units_happened = self.source_file_lines[
                                                new_error.
                                                linenr_of_multiple_unit_assignment
                                                - 1].strip()
                                # COLLECT ERROR / WARNING
                                self.all_errors.append(new_error)
                                break
 def error_check_logical_recursive_target(self, token, left_token,
                                          right_token):
     if self.debug_verbose:
         self.cps_units_checker.handle_debug_verbose(inspect.stack()[0][3])
     if token.isOp and token.str in [
             '&&', '||', '!'
     ]:  # NOT << and >> since theses are used in PRINT OUTS
         if (left_token and left_token.units) or (right_token
                                                  and right_token.units):
             # CREATE VARIABLE ERROR OBJECT
             new_error = UnitError(self.cps_units_checker)
             new_error.var_name = ''  # NO VAR NAME SINCE ITS A COMPARISON OPERATORS
             new_error.ERROR_TYPE = UnitErrorTypes.LOGICAL_OPERATOR_USED_ON_UNITS
             # LINENR
             new_error.set_primary_line_number(token.linenr)
             new_error.token_left = left_token
             new_error.token_right = right_token
             new_error.token = token
             # GET LINE FROM ORIGINAL FILE IF IT EXISTS
             if self.source_file_exists:
                 new_error.source_code_at_first_assignment = self.source_file_lines[
                     new_error.linenr_at_first_unit_assignment - 1].strip()
                 new_error.source_code_when_multiple_units_happened = self.source_file_lines[
                     new_error.linenr_of_multiple_unit_assignment -
                     1].strip()
             # COLLECT ERROR
             self.all_errors.append(new_error)
 def error_check_addition_of_incompatible_units_recursive_target(
         self, token, left_token, right_token):
     ''' ERROR CHECK ADDITIONAL OF INCOMPATIBLE UNITS - RESURSIVE TARGET
         input:  token   cppcheck token object
                 left_token, right_token
         returns: nothing, with possible side effect of adding errors
         '''
     if token.str in ['+', '-', '+=', '-=']:
         # if token.isArithmeticalOp and token.str in ['+', '-', '+=', '-=']:
         if self.debug:
             print 'found + or - or += or -='
         # THIS IS ADDITION OR SUBTRACTION
         # assert(token.astOperand1 and token.astOperand2)
         if token.astOperand1 and token.astOperand2:  # WEIRD IF THIS WERE FALSE
             if token.astOperand1.units and token.astOperand2.units:
                 # BOTH CHILDREN HAVE UNITS
                 if token.astOperand1.units != token.astOperand2.units:
                     if not self.have_found_addition_error_on_this_line:
                         # UNIT MISMATCH ON ADDITION : REPORT ERROR
                         new_error = UnitError(self.cps_units_checker)
                         new_error.var_name = ''  # NO VAR NAME SINCE ITS A COMPARISON OPERATORS
                         new_error.ERROR_TYPE = UnitErrorTypes.ADDITION_OF_INCOMPATIBLE_UNITS
                         new_error.is_unit_propagation_based_on_constants = token.is_unit_propagation_based_on_constants
                         new_error.is_unit_propagation_based_on_unknown_variable = token.is_unit_propagation_based_on_unknown_variable
                         if token.is_unit_propagation_based_on_constants or token.is_unit_propagation_based_on_unknown_variable:
                             new_error.is_warning = True
                         # LINENR
                         new_error.linenr = token.linenr
                         new_error.token_left = left_token
                         new_error.token_right = right_token
                         new_error.token = token
                         # GET LINE FROM ORIGINAL FILE IF IT EXISTS
                         if self.source_file_exists:
                             new_error.source_code_at_first_assignment = self.source_file_lines[
                                 new_error.linenr_at_first_unit_assignment -
                                 1].strip()
                             new_error.source_code_when_multiple_units_happened = self.source_file_lines[
                                 new_error.
                                 linenr_of_multiple_unit_assignment -
                                 1].strip()
                         # COLLECT ERROR
                         self.all_errors.append(new_error)
                         self.have_found_addition_error_on_this_line = True
Beispiel #7
0
    def error_check_multiple_units(self):
        ''' MULTIPLE_UNIT_TYPE ASSIGNMENT ERROR CHECKING IMPLEMENTATION 
            returns: none
            side_effects: might add UnitError objects to self.all_errors list
            '''
        for root_token, token, name, units, isKnownRhs in con.multi_unit_variables:
            new_error = UnitError()
            new_error.ERROR_TYPE = UnitErrorTypes.VARIABLE_MULTIPLE_UNITS
            new_error.linenr = token.linenr
            new_error.token = root_token
            new_error.token_left = token
            new_error.var_name = name
            new_error.units_when_multiple_happened = units
            new_error.dont_check_for_warning = isKnownRhs
            new_error.is_unit_propagation_based_on_constants = \
                    root_token.is_unit_propagation_based_on_constants
            new_error.is_unit_propagation_based_on_unknown_variable = \
                    root_token.is_unit_propagation_based_on_unknown_variable
            if new_error.is_unit_propagation_based_on_constants or \
                    new_error.is_unit_propagation_based_on_unknown_variable:
                new_error.is_warning = True

            if (not new_error.dont_check_for_warning) and (
                    new_error.linenr in self.marked_as_low_confidence):
                new_error.is_warning = True

            self.all_errors.append(new_error)
Beispiel #8
0
 def error_check_logical_recursive(self, token, left_token, right_token):
     if token.isOp and token.str in ['&&', '||', '!']:
         if (left_token and left_token.units) or (right_token
                                                  and right_token.units):
             # UNIT ERROR ON LOGICAL OPERATION
             new_error = UnitError()
             new_error.ERROR_TYPE = UnitErrorTypes.LOGICAL_OPERATOR_USED_ON_UNITS
             # LINENR
             new_error.linenr = token.linenr
             new_error.token_left = left_token
             new_error.token_right = right_token
             new_error.token = token
             new_error.var_name = self.get_var_name(left_token)
             new_error.is_unit_propagation_based_on_constants = token.is_unit_propagation_based_on_constants
             new_error.is_unit_propagation_based_on_unknown_variable = \
                     token.is_unit_propagation_based_on_unknown_variable
             if token.is_unit_propagation_based_on_constants or \
                     token.is_unit_propagation_based_on_unknown_variable:
                 new_error.is_warning = True
             # GET LINE FROM ORIGINAL FILE IF IT EXISTS
             if self.source_file_exists:
                 pass
             # COLLECT ERROR
             self.all_errors.append(new_error)
Beispiel #9
0
    def error_check_comparison_recursive(self, token, left_token, right_token):
        ''' COMPARISON OPERATORS - MUST BE THE SAME ON BOTH SIDES
            input:  token (cppcheck token object),
                    left_token, right_token
            returns: nothing, with possible side effect of adding errors
            '''
        if token.isComparisonOp:
            if left_token and left_token.units and right_token and right_token.units:
                # BOTH HAVE UNITS
                if left_token.units != right_token.units:
                    # UNIT MISMATCH ON COMPARISON
                    new_error = UnitError()
                    new_error.ERROR_TYPE = UnitErrorTypes.COMPARISON_INCOMPATIBLE_UNITS
                    # LINENR
                    new_error.linenr = token.linenr
                    new_error.token_left = left_token
                    new_error.token_right = right_token
                    new_error.token = token
                    new_error.var_name = self.get_var_name(left_token)
                    new_error.is_unit_propagation_based_on_constants = \
                            left_token.is_unit_propagation_based_on_constants or \
                            right_token.is_unit_propagation_based_on_constants
                    new_error.is_unit_propagation_based_on_unknown_variable = \
                            left_token.is_unit_propagation_based_on_unknown_variable or \
                            right_token.is_unit_propagation_based_on_unknown_variable
                    if new_error.is_unit_propagation_based_on_constants or \
                            new_error.is_unit_propagation_based_on_unknown_variable:
                        new_error.is_warning = True

                    if (not new_error.is_warning):
                        new_error.is_warning = self.check_if_error_with_low_confidence(
                            token, left_token, right_token)

                    # GET LINE FROM ORIGINAL FILE IF IT EXISTS
                    if self.source_file_exists:
                        pass
                    # COLLECT ERROR
                    self.all_errors.append(new_error)
Beispiel #10
0
    def error_check_addition_of_incompatible_units_recursive(
            self, token, left_token, right_token):
        ''' ERROR CHECK ADDITION OF INCOMPATIBLE UNITS - RESURSIVE TARGET
            input:  token (cppcheck token object),
                    left_token, right_token
            returns: nothing, with possible side effect of adding errors
            '''
        if token.str in ['+', '-', '+=', '-=']:
            # THIS IS ADDITION OR SUBTRACTION
            if token.astOperand1 and token.astOperand2:
                if token.astOperand1.units and token.astOperand2.units:
                    # BOTH CHILDREN HAVE UNITS
                    if token.astOperand1.units != token.astOperand2.units:
                        if not self.have_found_addition_error_on_this_line:
                            # UNIT MISMATCH ON ADDITION
                            new_error = UnitError()
                            new_error.ERROR_TYPE = UnitErrorTypes.ADDITION_OF_INCOMPATIBLE_UNITS

                            new_error.is_unit_propagation_based_on_constants = token.is_unit_propagation_based_on_constants
                            new_error.is_unit_propagation_based_on_unknown_variable = \
                                    token.is_unit_propagation_based_on_unknown_variable
                            if token.is_unit_propagation_based_on_constants or \
                                    token.is_unit_propagation_based_on_unknown_variable:
                                new_error.is_warning = True

                            if (not new_error.is_warning):
                                new_error.is_warning = self.check_if_error_with_low_confidence(
                                    token, left_token, right_token)
                                if new_error.is_warning:
                                    self.marked_as_low_confidence.append(
                                        token.linenr)

                            # LINENR
                            new_error.linenr = token.linenr
                            new_error.token_left = left_token
                            new_error.token_right = right_token
                            new_error.token = token
                            new_error.var_name = self.get_var_name(left_token)
                            # GET LINE FROM ORIGINAL FILE IF IT EXISTS
                            if self.source_file_exists:
                                pass
                            # COLLECT ERROR
                            self.all_errors.append(new_error)
                            self.have_found_addition_error_on_this_line = True